iOS 앱 만드는 기초 과정
//
// AppDelegate.swift
// B929_202212064
//
// Created by 소프트웨어컴퓨터 on 2025/09/29.
//
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}


//
// SceneDelegate.swift
// B929_202212064
//
// Created by 소프트웨어컴퓨터 on 2025/09/29.
//
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let _ = (scene as? UIWindowScene) else { return }
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
}
}



중요내용 복습

함수의 자료형 (Int,Int) -> Int
함수명
1) add(::)
2) add (first:second:)
3) add (_:_:)
4) add(_:with:)

함수명: tableView(_:numberOfRowsInSection:)
함수(tableView)의 자료형: (UITableView, Int) -> Int
함수명: tableView(_:cellForRowAt:)
함수(tableView)의 자료형: (UITableView, IndexPath) -> UITableViewCell
import Foundation //format을 쓰기 위한 라이브러리
func sss(x : Int, y : Int) -> (sum : Int, sub : Int, div : Double) //튜플로 리턴
{
let sum = x+y
let sub = x-y
let div = Double(x)/Double(y) //같은 자료형만 연산 가능
return (sum, sub, div)
} //2개의 정수를 입력받아 가감제 리턴
var result = sss(x:10,y:3)
print(result.sum)
print(result.sub)
print(result.div)
print(String(format:"%.2f",result.div)) // 소숫점 몇번째까지 출력하는지
print(type(of: sss)) //(Int, Int) -> (sum: Int, sub: Int, div: Double)
// 튜플을 반환하기 때문에 레이블까지 다 써야함

가변매개변수
func displayStrings(strings: String...) //가변 매개변수 데이터를 여러개 넣어도 상관없음
// "..."을 지우면 하나의 값만 출력 -> 오류발생
{
for string in strings {
print(string)
}
}
displayStrings(strings: "일", "이", "삼", "사")
displayStrings(strings: "one", "two")

inout매개변수:call by address 구현
var myValue = 10
func doubleValue (value: Int) -> Int {
value += value
return(value) //함수 내부의 변수는 상수임. 상수인 value를 두배해서 출력하려고 해서 오류발생.
// 기본적으로 call by value임. -> call by address로 구현 (inout parameter)
}
print(myValue)
print(doubleValue(value : myValue)) //출력 값? 레포트
print(myValue)

bmi 계산기

꿀팁 - alt 누른 후 물음표 표시 클릭하면 해당 변수의 자료형을 볼 수 있음.
import Foundation
let weight = 60.0
let height = 170.0
let bmi = weight / (height*height*0.0001) // kg/m*m
let shortEndBmi = String(format: "%.1f", bmi)
var body = ""
if bmi >= 40 {
body = "3단계 비만"
} else if bmi >= 30 && bmi < 40 {
body = "2단계 비만"
} else if bmi >= 25 && bmi < 30 {
body = "1단계 비만"
} else if bmi >= 18.5 && bmi < 25 {
body = "정상"
} else {
body = "저체중"
}
print("BMI:\(shortEndBmi), 판정:\(body)")
import Foundation //위 코드 변형
//let weight = 60.0
//let height = 170.0
func calcBmi (weight:Double,height:Double)-> String{
let bmi = weight / (height*height*0.0001) // kg/m*m
let shortEndBmi = String(format: "%.1f", bmi)
var body = ""
if bmi >= 40 {
body = "3단계 비만"
} else if bmi >= 30 && bmi < 40 {
body = "2단계 비만"
} else if bmi >= 25 && bmi < 30 {
body = "1단계 비만"
} else if bmi >= 18.5 && bmi < 25 {
body = "정상"
} else {
body = "저체중"
}
return "BMI:\(shortEndBmi), 판정:\(body)"
}
print(calcBmi(weight: 70.0, height: 170.0)) //값으로 return, print해줘야함
import Foundation //swithc-case로 변형
func calcBMI(weight : Double, height : Double) -> String {
let bmi = weight / (height*height*0.0001) // kg/m*m
let shortenedBmi = String(format: "%.1f", bmi)
var body = ""
switch bmi {
case 0.0..<18.5:
body = "저체중"
case 18.5..<25.0:
body = "정상"
case 25.0..<30.0:
body = "1단계 비만"
case 30.0..<40.0 :
body = "2단계 비만"
default :
body = "3단계 비만"
}
return "BMI:\(shortenedBmi), 판정:\(body)"
}
print(calcBMI(weight:60.0, height: 170.0))
1급 객체 (=1급 시민)
swift의 함수는 1급 객체임.
1) 변수에 저장할 수 있다.

함수를 받은 변수. 해당 변수의 자료형은 함수의 자료형으로 표현됨

func up(num: Int) -> Int {
return num + 1
}
func down(num: Int) -> Int {
return num - 1
}
let toUp = up // Swift 함수는 일급 객체로, 변수나 상수에 저장할 수 있음
print(up(num:10))
print(toUp(10)) //주의 : argument label인 (num:) 안 씀
// 함수를 변수에 할당하면 argument label(num:)을 생략해야 함
//소스 추가 완성 해보기
let toDown = down
print(down(num: 10))
print(toDown(10))

2) 매개변수로 전달할 수 있다.
"고차 함수(higher-order function)"
함수를 매개변수로 받거나 반환하는 함수 - JavaScript, python, Swift에서 많이 사용

func up(num: Int) -> Int {
return num + 1
}
func down(num: Int) -> Int {
return num - 1
}
let toUp = up // Swift 함수는 일급 객체로, 변수나 상수에 저장할 수 있음
print(up(num:10))
print(toUp(10)) //주의 : argument label인 (num:) 안 씀
// 함수를 변수에 할당하면 argument label(num:)을 생략해야 함
//소스 추가 완성 해보기
let toDown = down
print(down(num: 10))
print(toDown(10))
func upDown(Fun: (Int) -> Int, value: Int) { //함수를 매개변수로 사용
let result = Fun(value) //함수와 그 함수에 전달되는 변수
print("결과 = \(result)")
}
print(type(of: upDown)) // ((Int) -> Int, Int) -> ()
upDown(Fun:toUp, value: 10) //toUp(10)
upDown(Fun:toDown, value: 10) //toDown(10)
upDown(Fun: toUp, value: 76)

- up과 down 함수는 각각 입력값을 1 더하거나 빼는 역할
- toUp과 toDown은 해당 함수를 변수에 할당한 것
- 함수는 일급 객체이므로 변수에 저장, 매개변수로 전달 가능
- upDown 함수는 (Int) -> Int 타입의 함수를 받아 실행하는 함수
- 함수 타입을 출력해보면 (함수, Int) -> Void 형식임을 확인 가능
3) 반환값으로 사용할 수 있다.

func up(num: Int) -> Int {
return num + 1
}
func down(num: Int) -> Int {
return num - 1
}
let toUp = up // Swift 함수는 일급 객체로, 변수나 상수에 저장할 수 있음
print(up(num:10))
print(toUp(10)) //주의 : argument label인 (num:) 안 씀
// 함수를 변수에 할당하면 argument label(num:)을 생략해야 함
//소스 추가 완성 해보기
let toDown = down
print(down(num: 10))
print(toDown(10))
func upDown(Fun: (Int) -> Int, value: Int) { //함수를 매개변수로 사용
let result = Fun(value) //함수와 그 함수에 전달되는 변수
print("결과 = \(result)")
}
print(type(of: upDown)) // ((Int) -> Int, Int) -> ()
upDown(Fun:toUp, value: 10) //toUp(10)
upDown(Fun:toDown, value: 10) //toDown(10)
upDown(Fun: toUp, value: 76)
func decideFun(x: Bool) -> (Int) -> Int { //함수의 리턴형이 함수임. 헷갈리지 말 것.
//매개변수형 리턴형이 함수형
if x {
return toUp
} else {
return toDown
}
}
let r = decideFun(x:true) // let r = toUp
let a = decideFun(x:false) //let a = toDown
print(type(of:r)) //(Int) -> Int
print(r(10)) // toUp(10)
print(type(of:a)) //(Int) -> Int
print(a(10)) // toDown(10)
--고차함수 사용하는 프로그래밍 언어 순위

클로저
클로저 표현식 : 익명함수 또는 독립적인 코드 블록으로 클로저의 하위 개념 (클로저와 클로저 표현식은 다른 개념)
다른개념이지만 일반적으로 그냥 클로저라고 부름.



func add(x: Int, y: Int) -> Int {
return x+y
}
print(add(x:10, y:20))
let closureAdd = {(x: Int, y: Int) -> Int in
return x+y
}
print(closureAdd(1,3))
print(type(of: closureAdd)) //(Int, Int) -> Int
func mul(x: Int, y: Int) -> Int
{
return x * y
}
let result = mul(x:10, y:20)
print(result)
let closureMul = {(x: Int, y: Int) -> Int in
return x * y
}
let resultMul = closureMul(3,10)
print(resultMul)
후행클로져는 단축인자를 사용해서 다음 학기에 ㅎㅎ 이번 학기에는 안하는걸로 ㅎㅎ
클래스
이전까진 swift의 함수적인 언어를 배움
클래스부터는 swift의 객체지향적인 특징.

사용중인 객체 : instance
swift 에서는 property, method


구조체는 상속이 불가능, 클래스는 상속 가능. but class는 복잡성이 커 구조체를 많이 사용함.
간단한건 구조체, 복잡한건 클래스로
Class


클래스 만들었는데 발생한 에러 - 시험문제 ㅎ
-> 생성자를 만들어야함. or 프로퍼티에 초기값을 지정해야함. (stored property 는 초기값이 반드시 있어야함)

클래스 만들시 중요 point
1) stored property 는 초기값을 지정
class Human{
var age:Int = 0
var weight:Double = 0.0
}
2) 옵셔널 변수로 선언
class Human{
var age:Int? //옵셔널 변수는 nil로 자동 초기화
var weight:Double!
}
3) init으로 초기화
class Human{
var age:Int
var weight:Double
init(){ //initializer로 초기화, 함수인데 func안씀. "생성자"
age = 1
weight = 3.5
}
}



초기값을 지정하고 생성자로 초기값 지정해도 오류 발생 X, but 중복해서 작성할 필요 없음

class Man{
var age : Int = 1
var weight : Double = 3.5
// init(){ //작성하지 않아도,보이지 않아도 자동으로 생성: default initializer
//
// }
func display(){ //인스턴스 메서드
print("나이=\(age), 몸무게=\(weight)")
}
}
var x : Int = 10 //Int는 구조체임, 변수를 사용하기 위해 " = 초기값 " 형식으로 사용.
//클래스도 마찬가지. " = 클래스 () " 형식으로 작성해야함 -> init()이 자동으로 생성되기 때문
//var kim : Man kim 이라는 class를 초기화하기 이전에 사용하여 오류 발생
//var kim : Man = Man.init() //init 메서드의 경우 생략가능
var kim = Man()
print(kim.age)
print(kim.weight)
kim.display()
5주차도 끝~ ㅎㅎ 다음 수업에는 더 집중하도록.