2. IOS 개요
• Apple사의 스마트폰, 태블릿, 스마트 워치 등에 포함되어 있는
OS
• macOS의 축소판
• macOS를 터치패널을 가진 휴대용 기기에 최적화
• Cocoa(macOS 프레임워크) 기반의 애플리케이션 프레임워크
• Cocoa Touch
3. Cocoa Touch
• Cocoa 프레임워크의 축소판
• 주요 프레임워크
• Foundation: 문자열/수치 처리등 범용적인 클래스 라이브러리
• UIKit: UI부품 제공 라이브러리
• Map Kit: 지도 정보 제공 라리브러리
• iOS 앱 개발 지식의 상당수가 Cocoa Touch 프레임워크를 배우
는 것에 할당되어 있다.
4. IOS Version
버젼 출시 시기 발매당시 탑재 기기
2.0 2008.7 iPhone 3G
3.0 2009.6 iPhone 3GS
4.0 2010.6 iPhone 4
5.0 2011.10 iPhone 4s
6.0 2012.9 iPhone 5
7.0 2013.9 iPhone 5s, 5c
8.0 2014.9 iPhone 6, 6 Plus
9.0 2015.9 iPhone 6s, 6s Plus
10.0 2016.9 iPhone 7, 7 Plus
11.0 2017.9 iPhone 8, 8 Plus, X
5. IOS 디바이스의 해상도
디바이스 해상도(픽셀; 가로 x 세로) iOS로부터 바라본 해상도(포인트)
iPhone 3GS, 3GS 320 x 480 320 x 480
iPhone 4, 4s 640 x 960
iPhone 5, 5s, 5c 640 x 1,136 320 x 568
iPhone 6, 6s, 7, 8 750 x 1,334
iPhone 6 Plus, 6s Plus, 7 Plus,
8 Plus
1,080 x 1,920
iPhone X 1125 x 2436 375 x 667
iPad, iPad2, mini 768 x 1,024 768 x 1,024
iPad 3, 4세대, Air, Air 2,
Pro (9.7), mini 2, mini 3, mini 4
1,536 x 2,048
iPad Pro(12.9) 2,048 x 2,732 1,024 x 1,366
6. 앱 개발 준비사항
• 하드웨어
• Mac
• iOS 단말
• 소프트웨어
• Xcode
• 기타
7. 개발 언어 이해
• Objective-C
• C언어를 기반으로한 Smalltalk 타입의 객체지향 요소를 포함한 프로그
래밍 언어
• 2008년 7월(Xcode 3.1)부터 Swift지원을 발표한 2014년 9월(Xcode 6.0)
까지 iOS개발의 유일한 언어
• Swift
• 2014년 WWDC (Apple 개발자 이벤트)에서 발표된 iOS / macOS 개발
언어
• 모던, 안전한 설계, 빠르고 강력
10. Swift Api 사양
• https://developer.apple.com/library/content/documentation/S
wift/Conceptual/Swift_Programming_Language/index.html
• iBooks Store / Goole Play Book
• Swift Programming Language 검색
11. Swift 주석
• //
• /* */. 중첩해도 됨
•
• 세미콜론: swift에서는 필요없음(붙여도 문제없지만…)
• 단, 한행에 복수개의 문장 기술 필요시 사용
12. 변수
• 변수: swift에선 변수 사용전에 반드시 선언과 초기화가 필요
•
• var stringValue = "Hello, Swift". 형 추측
• var intValue = 10
•
•
• 변수의 선언과 초기화
• 선언만 하고 초기화하지 않으면 컴파일 에러 발생
• var stringValue: String = "Hello, Swift"
• var intValue: Int = 10
13. 정수:定數(=상수)
• 정수(상수)의 의미: 일단 선언, 초기화하면 값을 변경할 수 없다(나머지는 변수와 같음)
•
• let stringConst = "Hello, Swift"
• let intConst: Int = 30
•
• 값으로부터 형 추측
• var stringValue = "Hello, Swift"
• var boolValue = true
•
•
• 한 행에 복수개의 변수(정수) 정의 가능
• let x: Int = 100, y: Int = 200
16. • 마이너스(-) 연산자 전치의 의미
• let three = 3
• let minusThree = -three
• 비트 연산자(논리 부정)
• let binaryValue: UInt8 = 0b00000101
• ~binaryValue
•
• 복합대입 연산자
• 가산자, 감산자
• ++, --는 swift 1, 2 에서는 지원했지만 3이후에는 지원안함(안됨!)
• var a = 0
• a += 1
• a -= 1
17. • 비교 연산자
•
• let type = "apple"
• if type == "apple" {
• print("this is an apple")
• }
•
• let age = 18
• if age < 20 {
• print("술은 20세부터")
• }
18. • 삼항 연산자
• let age = 18
• print(age < 20 ? "미성년" : "성년")
•
• 논리연산자
• let age = 20
• let gender = "남성"
• if age >= 20 && gender == "남성" {
• print("성인 남성")
• }
20. 형변환
• 연산할 때, 좌우의 형이 다른 경우 원칙적으로, 어느쪽이든지의
수치를 변환해서 좌우의 형을 맟출 필요있다.
•
• let intValue: Int = 100
• let doubleValue: Double = 0.03
• intValue + doubleValue (오류!)
• Double(intValue) + doubleValue
21. 문자열
• 문자열
• "Hello, Swift"
• "It's an "apple""
•
• 빈문자열
• let emptyString1 = ""
• let emptyString2 = String()
•
• 문자열에서 식과 변수를 삽입
• let price = 300
• let message = "(price) x 3 = (price * 3)"
22. 튜플
• 2개 이상의 값을 조합해서 하나의 값으로 처리하는 것
• 튜플의 선언 & 참조
• let name = ("HyungKu", "Im")
• name.0. 인덱스 지정해서 참조
• name.1
•
• 변수로서 다른 튜플에 대입가능
• let (firstName, familyName) = name
• firstName
• lastName
•
23. •
• 튜플에 항목명 붙이는 것 가능. 인덱스 대신에 사용(인덱스
참조도 가능)
• let name = (familyName: "Im", firstName: "Hyungku")
• name.firstName
• name.familyName
24. Optional 형
• Swift 특유의 언어요소중 하나(가장 중요! 빈번히 사용됨)
• 변수에서 nil, Optional 형이란?
• “안전을 위한 설계”중 하나로 Optional형 도입
•
• 변수내용이나 메서드의 리턴값이 nil일 가능성을 프로그램에
명시적으로 함으로, 개발자가 버그를 발생했을 때, 컴파일
경고나 에러가 나오도록 함
25. Nil
• Nil이란 “값이 존재하지 않음”을 나타내는 특별한 값(다른
언어에서 null)
•
• Nil의 용도
• 메서드 리턴값으로 성공했을 때 기대되는 값, 실패했을 때 nil
• 메서드 인수로서 지정하려는 경우 지정하려는 값, 생략하려는 경우
nil를 전달
• 객체의 프로퍼티의 초기화하기 전에 값으로서 nil을 가짐
26. • var str: String = "Hello, Swift"
• str = nil // 컴파일 에러
•
• 초기화하지 않아도 값이 nil이 됨
• var optionalString: Optional<String>
•
• optionalString = "Hello, Swift"
• optionalString = nil
•
• 선언과 초기화 동시에 가능
• var optionalInt: Optional<Int> = 255;
28. Forced Unwrapping (강제 언랩)
• var unwrappedString: String = optionalString!
• unwrappedString.lowercased()
•
• optionalString!.lowercased()
•
• 원래 형이 nil일 경우 런타임 에러 발생해서 앱에 강제종료됨
•
• Forced Unwrapping을 사용할 경우, 내용이 nil이 아닌 것을 감안하는 경우나,
내용이 nil인지 확인해서 사용
• if optionalString != nil {
• optionalString!.lowercased()
• }
29. Optional Binding
• 내용이 nil인지 확인과 언랩을 동시에 수행하는 구문
•
• var optionalString: Optional<String> = "Hello, Swift"
• if let unwrappedString = optionalString {
• unwrappedString.lowercased()
• }
30. Optional Chaning
• 원래 형 자체로 사용하려고 할 때 사용
• “값이 nil이 아니면 처리하고 nil이면 아무 것도 하지 않음”
• 하지만 원래의 형의 값으로 처리되는 것은 아님
•
• optionalString?.lowercased()
31. Implicitly Unwrapped Optional
• 자동적으로 언랩
• var optionalString: ImplicitlyUnwrappedOptional<String> =
"Hello, Swift"
• optionalString.lowercased()
•
• 원래의 형이 nil일 경우 런타임에러 발생 가능성 있음
• Nil체크(if문 사용) 할 수 있지만, 그럴 경우 Optional형을
사용하고 nil이 아닐 경우를 선언시에 확정한 경우
ImplicitlyUnwrappedOptional를 사용
32. Optional 형의 생략
• var optionalString: String? = "Hello, Swift"
• var optionalInt: Int! = nil
•
• func foo(bar: String) -> String? {
• return nil
• }
33. Swift 배열
• var fruits: Array<String>
• var animals: [String]
•
• let도 사용가능 단, 요소의 갱신 추가 삭제는 안됨
•
• 초기화
• var animals: [String] = [“dog”, “cat”, “tiger”]
• var fruits: [String] = Array<String>()
• var planets: [String]= [String]()
36. • 기타 배열의 메서드 정리
• filter: 필터 매치되는 것이 없다면 요소 수가 0인 배열
• fruits.filter{ $0 == “lemon”}
•
•
• first: 첫번째 요소 비어 있다면 nil(Optional)
• fruits.first
•
• isEmpty: 요소가 없으면 true 아니면 false
• fruits.isEmpty
•
• last: 마지막 요소 비어 있다면 nil(Optional)
• fruits.last
•
• removeAll: 전부 삭제
• fruits.removeAll()
37. 딕셔너리
• 딕셔너리 선언
• var airports: Dictionary<String, String>
• var pixels: [String: [Int]]
• 딕셔너리 초기화
• var airports: [String: String] = [
• "GMP": "Gimpo",
• "ICN": "Inchon",
•
• ]
다른 언어의 연상
배열, 맵과 같은
개념
41. For – in 루프 구문
• for 변수 in 일련의 값 {
• 루프할 처리
• }
42. • for var idx: Int; idx < 10; idx++ {
•
• }
• 범위를 대상
• for idx in 1...10 {
• print(idx)
• }
• 인덱스 생략
• for _ in 1...10 {
• print("hello")
• }
Swift 1,2 에
서 사용가능,
3> 는 안됨
Swift 3> 에
서는 이렇게
43. • 배열 대상
• let fruits = ["apple", "banana", "orange"]
• for item in fruits {
• print(item)
• }
• 딕셔너리 대상
• var airports = ["GMP": "Gimpo", "ICN":"Inchon",]
•
• for index in airports {
• print(index.0 + "," + index.1)
• }
•
44. • for (code, name) in airports {
• print(code + "," + name)
• }
• 문자열 대상
• for char in "안녕하세요Swift".characters {
• print(char)
• }
45. while / repeat - while
• while 조건 {
• 루프할 처리
• }
• repeat {
• 루프할 처리
• } while 조건
47. if
• if 조건 {
• 조건이 true일 경우 처리
• } else {
• 조건이 false일 경우 처리
• }
• var str = ""
• if str == "" {
• print("문자열은 빈문자열입니다")
• }
48. switch-case
• switch 평가할 값 {
• case 값1:
• 값1에 대응하는 처리
• case 값2, 값3:
• 값2와 값3에 대응하는 처리
• default:
• 그이외의 값이 대응하는 처리
• }
49. • let character = "b"
• switch character {
• case "a", "b":
• print("a or b")
• default:
• print("default")
• }
case문에 하나씩만 매
칭이 된다!
50. • enum ButtonColor {
• case Black
• case Red
• case Blue
• //case Green
• }
•
• let buttonColor = ButtonColor.Black
•
• switch buttonColor {
• case ButtonColor.Black:
• print("Black")
• case ButtonColor.Red:
• print("Red")
• case ButtonColor.Blue:
• print("Blue")
• }
모든 값을 커버할 필요!
51. • let hour = 15
• switch hour {
• case 10...12, 13...19:
• print("영업시간내입니다")
• default:
• print("영업시간외입니다")
• }
범위에 대한 매칭
53. • let point = (40, 0)
• switch point {
• case (0, 0):
• print("센터마크 위")
• case (0, _):
• print("센터라인 위")
• case (_, 32), (_, -32):
• print("터치라인 위")
• case (-50...(-34), -16...16), (34...50, -16...16):
• print("페널티에리어 내")
• default:
• print("그 외의 필드")
• }
튜플에 대한 매칭
54. • let point = (0, -20)
• switch point {
• case (0, let y):
• print("센터라인 위")
• if y > 0 {
• print("북측")
•
• } else {
• print("남측")
• }
• default:
• print("그 외의 필드")
• }
55. • let point = (0, -20)
• switch point {
• case (0, let y) where y > 0:
• print("센터라인 위 북측")
• case (0, let y) where y < 0:
• print("센터라인 위 남측")
• case (0, _)
• print("센터라인 위")
• default:
• print("그 외의 필드")
• }
56. continue
• let arr = 1...100
• for idx in arr {
• if idx % 2 == 1 {
• continue
• }
• print("(idx)은 짝수")
• }
현재의 루프를 종료하고 다음 루프를 시작
57. break
• let haystack = ["Mercury", "Venus", "Earth", "Mars", ]
• let needle = "Earth"
•
• for word in haystack {
• if word == needle {
• print("(needle) found")
• break
• }
• }
현재의 루프를 종료함. 남은 루프를 실행하지 않음
58. fallthrough
• let number = 10
• switch number {
• case 1...10:
• print("1이상 10이하의")
• fallthrough
• default:
• print("정수입니다")
• }
fallthrough를 만나면 다음의 case절이나 default절도 같이 실행한다. case조건과는 상관없음
59. label 명령
• loop1: for idx1 in 1..<10 {
• loop2: for idx2 in 1..<10 {
• print("idx1: (idx1) idx2: (idx2)")
• if idx1 == 4 && idx2 == 4 {
• break loop1
• }
• }
• }
continue나 break문은 루프를 유지하거나 종료한다. 하지만 대상이 자신이 포함되어 있는
가장 가까운 루프이다. 이 이외의 루프를 대상으로 하고 싶을 때 라벨 명령을 사용한다
66. 가변 파라미터(...)
• func sum(_ numbers: Int...) -> Int {
• var sum = 0
• for number in numbers {
• sum += number
• }
• return sum
• }
•
• sum(1, 2, 3, 4, 5)
67. 변경 가능한 파라미터 변수(inout)
• func swap(a: inout Int, b: inout Int) {
• let temp = a
• a = b
• b = temp
• }
•
• var a = 1
• var b = 2
• swap(&a, &b)
68. 함수형
• func add(a: Int, b: Int) -> Int {
• return a + b
• }
•
• func multiply(a: Int, b:Int) -> Int {
• return a * b
• }
•
모든 함수는 독자적인 함수형을 가진다.
(Int, Int) -> Int
69. 함수형의 정의
• var calcFunc: (Int, Int) -> Int = add
•
• calcFunc(1, 2)
•
• calcFunc = multiply
•
• calcFunc(1, 2)
70. • func zero(a: Int, b:Int) -> Int {
• return 0
• }
•
• func getCalcFunc(name: String) -> (Int, Int) -> Int {
• switch name {
• case "add":
• return add
• case "multiply":
• return multiply
• default:
• return zero
• }
• }
•
• getCalcFunc(name: "add")(3, 4)
• getCalcFunc(name: "multiply")(3, 4)
함수형을 사용하는 함수
71. 클로저
• 함수처럼, 일련의 처리를 합쳐놓을 것
• 매개변수, 리턴값을 가진다
• 이름이 없다
• {
• (파라미터) -> 리턴타입 in
• 처리 내용
• }
예
{
(a: Int, b: Int) -> Bool in
return a < b
}
72. 함수를 사용한 sorted 함수 사용 예
• func compare(_ a: Int, _ b: Int) -> Bool {
• return a < b
• }
•
• compare(3, 5)
• var arr = [3, 5, 1, 2, 4]
• arr.sorted(by: compare)
73. 클로저를 사용한 sorted 함수 사용 예
• arr.sorted(by: {
• (a: Int, b: Int) -> Bool in
• return a < b
• })
89. 타입 프로퍼티
• class Foo {
• static var stored: Int = 100
• static var computed: Int {
• return 200
• }
• class var overridableComputed: Int {
• return 300
• }
• }
90. self – 특별 프로퍼티
• 인스턴스 자기 자신을 가리킴
• 통상, self를 사용할 필요 없음
• 메서드의 파라미터와 클래스의 프로퍼티가 이름이 같을 때 명
시적으로 클래스의 프로퍼티를 지정할 때 사용
91. 프로퍼티 옵저버
• 프로퍼티에 값을 설정할 때마다 호출되는 함수
• willSet
• 값을 설정하기 전에 호출
• didSet
• 값이 설정된 후 호출
97. 타입 메서드
• class Foo {
• static func typeMethod() {
• print("typeMethod")
• }
•
• class func overridableTypeMethod() {
• print("overridableTypeMethod")
• }
• }
98. 상속
• 메서드나 프로퍼티 기타 기능을 다른 클래스에서 물려받을 수
있다.
• 클래스 A가 클래스 B로부터 상속받는 경우,
• 클래스 A를 서브 클래스, 클래스 B를 수퍼 클래스라고 함
• 서브 클래스는 수퍼 클래스가 가진 기능을 덮어써서 새로운 기
능으로 치환 가능
• 서블 클래스는 수퍼 클래스에 없는 새로운 기능을 추가 가능
108. • var d1 = Distance(fromMeter: 10)
• d1.distanceInKm
• var d2 = Distance(fromMile: 10)
• d2.distanceInKm
109. 실패가능한 이니셜라이저
• import Foundation
•
• let urlOptional = URL(string: "http://www.naver.com")
• if let url = urlOptional {
• print("(url) is success")
• } else {
• print("fail")
• }
110. • class Sample {
•
• init?(name: String) {
• if name.isEmpty {
• return nil
• }
• print("당신의 이름은 (name)")
• }
•
• }
var s = Sample(name: "HyungKu Im")
if let name = s {
print("name is success")
} else {
print("fail")
}
111. 이니셜라이저의 규칙
• class Instrument {
• var rangeOfOctaves = 0
• var description: String {
• return "(rangeOfOctaves) 옥타브의 음이 나옵니다"
• }
•
• func play() {
•
• }
• }
112. 컨비니언스 이니셜라이저
• 클래스에서 필수는 아니지만, 이름대로 클래스 초기화에 “편리”
를 위한 이니셜라이저로서, 내부적으로 지정이니셜라이저를 실
행한다
• convenience init (파라미터) {
• 초기화내용
• }
113. 이니셜라이저의 규칙
• 서브클래스의 지정이니셜라이저에서는 자신이 정의한 스토어드프로
퍼티를 초기화한 후에 수퍼클래스의 지정이니셜라이저를 실행한다
• 서브클래스의 지정이니셜라이저는 수퍼클래스에서 상속받은 프로퍼
티에 값을 설정하기 전에 수퍼클래스의 지정이니셜라이저를 실행한
다
• 컨비니언스이니셜라이저는 프로퍼티에 값을 설정하기 전에 다른 이
니셜라이저를 실행한다
• 이너셜라이저는 자신이 정의한 스토어드프로퍼티의 초기화 및 수퍼
클래스의 지정이니셜라이저의 실행이 완료되기 전에 다른 인스턴스
메서드를 실행하거나 인스턴스프로퍼티의 값이나 self를 참조하거나
할 수 없다
115. 함수 혹은 클로저를 사용한 초기화
• import Foundation
•
• class Dice {
• var spot: UInt32 = {
• return arc4random_uniform(6)
• }()
• }
for _ in 1...100 {
var d = Dice()
print(d.spot)
}
116. 형의 캐스팅
• class MediaItem {
• var title: String
• init(title: String) {
• self.title = title
• }
• }
•
• class CD: MediaItem {
• var artist: String
• init(title: String, artist: String) {
• self.artist = artist
• super.init(title: title)
• }
• }
• class DVD: MediaItem {
• var director: String
• init(title: String, director: String) {
• self.director = director
• super.init(title: title)
• }
• }
•
• let mediaLibrary = [
• CD(title: "Music", artist: "소녀시대"),
• CD(title: "Music", artist: "AKB"),
• DVD(title: "라라랜드", director: "데이미언 셔젤"),
• DVD(title: "그것만이 내세상", director: "최성현"),
• ]
117. 형 체크 연산자 is
• for item in mediaLibrary {
• if item is CD {
• print("CD: (item.title))")
• } else if item is DVD {
• print("DVD: (item.title))")
• }
• }
118. 다운캐스트
• as? 결과를 Optional형으로 리턴
• as! 지정한 형으로 다운캐스트 가능하지만, 실패할 경우 런타임에러
• for item in mediaLibrary {
• if let cd = item as? CD {
• print("CD: '(cd.title)', artist: '(cd.artist)'")
• } else if let dvd = item as? DVD {
• print("DVD: '(item.title)', director: '(dvd.director)'")
• }
• }
119. AnyObject 형과 Any형
• AnyObject형
• 모든 클래스를 포함하는 형에 사용가능
• 다운캐스트 연산자(as?, as!)를 사용해서 다운캐스트해서 사용
• Any형
• Int, String, 구조체, 클래스등 함수형을 포함한 모든 형에 사용가능
120. 프로토콜
• 클래스 메서드나 프로퍼티 설계만 정의하는 기능
• Cocoa Touch 프레임워크의 델리게이트는 프로토콜로 정의됨
protocol SomeProtocol {
var someProperty: Int { get set }
var someReadOnlyProperty: Int { get }
static func someTypeMethod()
func someInstanceMethod(str: String) -> String
}
137. 에디터Area
• 네비게이터에서 선택한 파일에 따른 변화가 심함
• 인터페이스빌더:
• Main.storyboard를 선택할 경우 나타냄
• 앱 화면에 UI부품을 배치하는 도구
• 어시스턴스에디터:
• 에디터Area를 좌우로 분리되었을 경우 우측의 영역을 가리킴
138. 인스펙터Pane
• 편집중인 대상에 대한 정보 표시, 설정할 경우 사용
아이콘 의미 설명
파일인스펙터
퀵헬프인스펙터
아이덴티티인스펙터 파일의 메타데이터. 주로 선택
한 UI 부품에 대응 클래스 지정
어트리뷰트인스펙터 UI부품의 폰트, 글자색 등 속성
관리
사이즈인스펙터 위치, 사이즈 지정
커넥션인스펙터 Outlet, Action, delegate등의 설
정상황 표시, 관리
139. Xcode단축키
단축키 동작
Command + 0 네비게이터 에리어 개폐
Command + 1~9 네비게이터 에리어 전환. 1은 프로젝트네비게이터, 9는 리포트
Command + shift + y 디버그 에리어 개폐
Command + option + 0 유틸리티 에리어 개폐
Command + option + 1 ~ 6 유틸리티 에리어 전환 왼쪽 아이콘순으로 1~6
Command + option + return 어시스턴스 에디터 열기
Command + return 어시스턴스 에디터 닫기
Command + r 앱 실행
Command + control + <- 파일 편집 이력을 하나씩 돌리기
Command + control + -> 파일 편집 이력을 하나씩 전진하기
Command + f 파일내 검색
Command + shift + f 프로젝트내 검새
Control + i 프로그램 들여쓰기 정돈
Command + / 선택한 행의 코멘트 아웃/ 코멘트 해제