Swift 4 변경사항

Swift 2017.06.23 11:00


오늘의 주제

스위프트 4 추가/변경사항


아, 벌써 스위프트가 4번째 버전이 나오네요! 참으로 빠르게 변합니다. 이제 문법적으로 변경되는 부분이 크게 많지 않아서 서 3 버전과 크게 달라진 문법은 많지 않습니다. 내부적으로 수정되거나 추가된 문법이 많고, 삭제된 부분은 거의 없습니다.

긴 말 필요없이 한 번 무엇이 바뀌었는지 살펴볼까요?

스따뚜~~~~~~~~~~~~


단방향 범위 연산자

이제 범위연산자에서 양 쪽 끝을 모두 신경쓸 필요가 없습니다, 야호! [SE-0172]

var numbers = [1, 2, 3, 4, 5]

// Swift 3
numbers[2..<numbers.endIndex] // [3, 4, 5]
numbers[0...2] // [1, 2, 3]
numbers[0..<2] // [1, 2]

// Swift 4
numbers[2...] // [3, 4, 5]
numbers[...2] // [1, 2, 3]
numbers[..<2] // [1, 2]

numbers = []

// Swift 3
//numbers[0...numbers.endIndex] // out of range - error

// Swift 4
numbers[0...] // []


let number: Int = 100

// Swift 3
switch number {
case Int.min..<0:
    print("negative")
case 0:
    print("zero")
case 1...Int.max:
    print("positive")
default:
    print("unknwon")
}


// Swift 4
switch number {
case ..<0:
    print("negative")
case 0:
    print("zero")
case 1...:
    print("positive")
default:
    print("unknwon")
}


 

String의 많은 변화

Swift 4에서 String은 정말 많은 변화가 있는 부분 중 하나입니다. 그 중 눈에 띌만한 내용을 위주로 정리했습니다. 더 많은 사항은 [String Processing For Swift 4] 문서를 참고해보시기 바랍니다.


String 구조체가 다시 Collection 프로토콜을 따릅니다. [SE-0163]

var greeting: String = "Hello, Swift!"

// Swift 3
greeting.characters.forEach { print($0) }
print(greeting.characters.count) // 13

// Swift 4
greeting.forEach { print($0) }
print(greeting.count) // 13


Unicode 9이 적용되었습니다. [String Processing For Swift 4 - Unicode 9 Conformance]

이전에 문자열 길이 결과가 제각각이었던 유니코드 문자들이 사람이 인지할 수 있는 단위로 세어집니다.

// Swift 3
"😍".characters.count // 1
"🇰🇷".characters.count // 1
"🐻".characters.count // 1
"🙌🏻".characters.count // 2
"🙌🏾".characters.count // 2
"‍‍👨‍👨‍👦".characters.count // 3
"‍‍‍👨‍👨‍👦‍👦".characters.count // 4

// Swift 4
"😍".count // 1
"🇰🇷".count // 1
"🐻".count // 1
"🙌🏻".count // 1
"🙌🏾".count // 1
"‍‍👨‍👨‍👦".count // 1
"‍‍‍👨‍👨‍👦‍👦".count // 1


여러 줄 리터럴 문법이 생겼습니다. [SE-0168]

  • 큰따옴표 세 개를 연결하여 표현하면 여러 줄 문자열을 표현하는 리터럴 문법입니다.   
  • 반드시 """ 다음 줄부터 문자열을 입력해야하며, 문자열 마지막 줄 다음줄에 """로 닫아줘야 합니다.

// Swift 3
greeting = "Hello\nHow are you?\nI'm fine thanks, and you?"

// Swift 4
greeting = """
Hello
How are you?
I'm fine thanks, and you?
"""


Substring 타입과 StringProtocol 프로토콜이 생겼습니다.

기존에 String 타입에 구현되어있던 주요 기능을 StringProtocol에 기본구현 하였습니다.

let subIndex = greeting.index(greeting.startIndex, offsetBy: 4)

// Swift 3
let subGreeting = greeting[greeting.startIndex...subIndex]
print(type(of: subGreeting)) // String

// Swift 4
let subGreeting = greeting[...subIndex]
print(type(of: subGreeting)) // Substring
let stringFromSubstring: String = String(subGreeting)


Character 타입에 unicodeScalars 프로퍼티가 추가되었습니다. [SE-0178]

Swift 3에서는 Character 인스턴스의 유니코드 스칼라 값을 알아내려면 String 타입으로 변환하여야 했지만, 이제는 바로 Character 인스턴스의 unicodeScalars 프로퍼티를 이용해 알아낼 수 있습니다.

let character: Character = ""

// Swift 3
print(String(character).unicodeScalars)

// Swift 4
print(character.unicodeScalars)


DictionarySet

자주 사용하는 콜렉션 타입인 DictionarySet의 기능이 한층 강화되었습니다.  

[SE-0154], [SE-0165]


키와 값의 시퀀스를 통해 새로운 딕셔너리를 생성할 수 있습니다. 또, 키와 값을 기존의 딕셔너리에 병합할 수 있습니다.

let zipSequence = zip("abcdefghijklmnopqrstuvwxyz", 97...)
let asciiTable = Dictionary(uniqueKeysWithValues: zipSequence)
// ["w": 119, "n": 110, "u": 117, "v": 118, "x": 120, "q": 113, ...]

let vegetables = ["tomato", "carrot", "onion", "onion", "carrot", "onion"]
let vegetableZipSequence = zip(vegetables, repeatElement(1, count: Int.max))

var vegetableCounts = Dictionary(vegetableZipSequence, uniquingKeysWith: +)
vegetableCounts.merge([("tomato", 1)], uniquingKeysWith: +)
// ["tomato": 2, "carrot": 2, "onion": 3]


DictionarySetfilter 결과가 이제 Array대신 각각의 원래 타입으로 반환됩니다. 또, 딕셔너리는 mapValues(_:) 메서드를 통해 값이 변형된 새로운 딕셔너리를 만들 수 있습니다.

let vowels: Set<Character> = ["a", "e", "i", "o", "u"]
let asciiVowels = asciiTable.filter({ vowels.contains($0.key) })

// Swift 3
print(type(of: asciiVowels)) // Array<(key : Character, value : Int)>

// Swift 4
print(type(of: asciiVowels)) // Dictionary<Character, Int>
asciiVowels["a"]  // 97
asciiVowels["b"]  // nil

let filteredSet: Set<Character> = vowels.filter{ $0 < "h" }

// Swift 3
print(type(of: filteredSet)) // Array<Character>

// Swift 4
print(type(of: filteredSet)) // Set<Character>

// Swift 3
let strangeMap = asciiTable.map { [$0: "0x" + String($1, radix: 16)] }
print(type(of: strangeMap)) // Array<Dictionary<Character, String>>
// [["u": "0x75"], ["v": "0x76"], ["w": "0x77"], ["x": "0x78"], ["q": "0x71"], ["n": "0x6e"], ...]

// Swift 4
let asciiHexTable = asciiTable.mapValues({ "0x" + String($0, radix: 16) })
// ["w": "0x77", "n": "0x6e", "u": "0x75", "v": "0x76", "x": "0x78", ...]


딕셔너리 서브스크립트 문법이 추가되었습니다. 원하는 키에 해당하는 값이 없으면 nil 대신 기본값을 돌려줍니다. 

기본값이 있다는 것은 값이 항상 존재한다는 의미이므로, 해당 서브스크립트의 반환값은 옵셔널이 아닌 값이라는 뜻입니다. 딕셔너리 옵셔널 전쟁에서 해방될 수도!

let favoriteSubject: [String: String] = ["yagom": "swift", "hana": "communication", "jisu": "swift"]

// Swift 3
type(of: favoriteSubject["minji"]) // Optional<String>

// Swift 4
type(of: favoriteSubject["minji"]) // Optional<String>
type(of: favoriteSubject["minji", default: "unknown"]) // String

var favoriteCount = [String: Int]()

favoriteSubject.forEach { favoriteCount[$0.value, default: 0] += 1 }
print(favoriteCount) // ["swift": 2, "communication": 1]


init(grouping:by:) 이니셜라이저를 통해 특정 조건에 따라 Array 또는 다른 시퀀스를 딕셔너리 형태로 그룹지을 수 있습니다. 그룹 기준값은 딕셔너리의 키가 됩니다.

struct Person: CustomStringConvertible {
    enum Gender {
        case male, female, unknwon
    }
    
    let name: String
    var gender: Gender
    
    var description: String { return name }
}

let yagom = Person(name: "yagom", gender: .male)
let hana = Person(name: "hana", gender: .female)
let jisu = Person(name: "jisu", gender: .unknwon)
let eric = Person(name: "eric", gender: .male)
let mike = Person(name: "mike", gender: .male)

let friends = [yagom, hana, jisu, eric, mike]
let friendsByGender = Dictionary(grouping: friends, by: { $0.gender })
print(type(of: friendsByGender))    // Dictionary<Gender, Array<Person>>
print(friendsByGender)
// [Person.Gender.unknwon: [jisu], Person.Gender.male: [yagom, eric, mike], Person.Gender.female: [hana]]


reserveCapacity(_:) 메서드를 통해 Array 처럼 예약된 공간을 가질 수 있습니다.

var emptyDictionary = [String: String]()
print(emptyDictionary.capacity) // 0
emptyDictionary.reserveCapacity(100)
print(emptyDictionary.capacity) // 192
// 최소 100개의 요소가 들어갈 수 있도록 공간을 확보하기 때문에 꼭 100이지 않을 수 있습니다
emptyDictionary.reserveCapacity(10)
print(emptyDictionary.capacity) // 192
emptyDictionary.reserveCapacity(1000)
print(emptyDictionary.capacity) // 1536


Key path

Cocoa에서 단순한 문자열로 표현하던 key path를 스위프트에서는 정확한 타입(KeyPath 라는 제네릭 클래스) 방식으로 표현합니다. 조금 더 안전한 동적 프로그래밍을 할 수 있지 않을까 기대됩니다. [SE-0161]

  • key path를 통하여 프로퍼티에 접근할 수 있도록 모든 타입에 자동으로 [keyPath:] 서브스크립트 메서드가 추가됩니다.
  • key path는 백슬래시(\)를 통해 표현합니다.

struct Person {
    var name: String
}

struct Stuff {
    var name: String
    var owner: Person
}


var yagom = Person(name: "yagom")
let macbook = Stuff(name: "macbook pro", owner: yagom)

print(type(of: \Person.name)) // WritableKeyPath<Person, String>

var result: Any = macbook[keyPath: \Stuff.name]
print(result) // macbook pro

let keyPath = \Stuff.owner
let nameKeyPath = keyPath.appending(path: \.name)

result = macbook[keyPath: nameKeyPath]
print(result) // yagom

result = macbook[keyPath: \Stuff.owner.name]
print(result) // yagom


프로토콜 혼합 타입

Objective-C 에서 특정 클래스와 프로토콜을 동시에 따르고 있는 타입이라는 의미로 사용되었던 표현이 있습니다. 

SomeClass<SomeProtocol, AnotherProtocol> *name
// SomeProtocol과 AnotherProtocol을 준수하는 SomeClass 타입의 변수 name

이 표현이 이제 스위프트에서도 가능해졌습니다. [SE-0156]

class ClassA { }
class ClassB: ClassA { }
protocol ProtocolA { }
extension ClassB: ProtocolA { }

var someVariable: ClassA & ProtocolA
// someVariable = ClassA()
// 오류발생 : ProtocolA를 충족하지 않음

someVariable = ClassB() // 모든 조건 충족


where 확장

프로토콜과 그 연관 타입에 where 절을 사용하여 타입 제약을 줄 수 있습니다. [SE-0142]

protocol StringRepresentable: RawRepresentable
where RawValue == String { }

protocol RawStringWrapper {
  associatedtype Wrapped: RawRepresentable
    where Wrapper.RawValue == String
}



제네릭 서브스크립트

서브스크립트가 이제 제네릭 매개변수와 반환 타입을 사용할 수 있게 되었습니다. [SE-0148]

struct CustomModel<Key: Hashable, Value> {
    var dictionary: [Key: Value]
    
    subscript<T>(key: Key) -> T? {
        return dictionary[key] as? T
    }
}

let information = CustomModel(dictionary: ["name": "yagom", "age": 100, "height": 183.0])
let name: String? = information["name"] // yagom


Private 접근수준의 변경

기존의 private 접근수준은 같은 파일인 여부와 상관없이 private 요소를 해당 범위를 벗어나면 사용할 수 없었습니다. 대체제로 fileprivate를 사용하였는데, 이는 문제를 야기할 수 있는 가능성을 가지고 있습니다. 같은 파일이라도 접근을 원치 않는 요소가 있는데, extension 등으로 타입을 확장하여 요소를 사용려면 fileprivate로 지정해 주어야 하는 문제가 있었기 때문이죠. 아래 Swift 3의 예를 먼저 보겠습니다.

// Swift 3
struct Person {
    var name: String
    // private로 지정하면 extension에서 접근할 수 없기 때문에 fileprivate로 선언
    fileprivate var age: Int = 0
    init(name: String) {
        self.name = name
    }
}

extension Person {
    mutating func passedYear() {
        self.age += 1
    }
}

var yagom = Person(name: "yagom")
yagom.passedYear()
yagom.age // 접근가능! 원하던 시나리오가 아님!


나이라는 민감한 부분은 숨기고 싶었기 때문에 private로, 어디서든 접근을 막고 싶었지만, 같은 파일의 익스텐션에서 조차 접근할 수 없기 때문에 fileprivate로 접근수준을 지정했습니다. 그 결과, 엉뚱하게 같은 파일의 다른 소스에서도 접근할 수 있게 되었습니다.

// Swift 4

struct Person { var name: String private var age: Int = 0 init(name: String) { self.name = name } } extension Person { mutating func passedYear() { // private라도 같은 파일의 extension에서 접근 가능 self.age += 1 } } var yagom = Person(name: "yagom") yagom.passedYear() // yagom.age // 접근불가

Swift 4에서는 이 문제를 개선하여 같은 파일의 익스텐션에서는 접근할 수 있도록 변경되었습니다.


아카이브와 시리얼라이제이션 / JSON 인코딩

NSCodingNSObject를 손쉽게 사용할 수 있는 클래스 타입을 제외하고, 구조체나 열거타입에서는 아카이빙이 참으로 난해했습니다. 물론 NSObject를 상속받지 않는 스위프트 고유 클래스도 마찬가지였습니다. 그러나 이제 타입이 스스로 어떻게 아카이브하고 시리얼라이즈 할지 정의할 수 있게 되었습니다. 그저 타입과 그 타입의 하위 타입이 모두 Codable 프로토콜을 준수하면 아카이브하고 그것을 풀어낼 수 있도록 할 수 있습니다. 기존에 사용하던 NSKeyedArchiver 클래스도 Codable 프로토콜을 완벽히 지원합니다. Codable과 함께 JSONEncoder, JSONDecoder로 인해 JSON 인코딩과 디코딩이 엄청나게 편해졌습니다!! 으아아아아아아아~!! [SE-0166],  [SE-0167]

struct Person: Codable {
    enum Gender: String, Codable {
        case male, female, unknown
    }
    
    var name: String
    var age: Int
    var gender: Gender
    var friends: [Person]
}

let yagom = Person(name: "yagom", age: 20, gender: .male, friends: [])
let hana = Person(name: "hana", age: 22, gender: .female, friends: [yagom])
let eric = Person(name: "eric", age: 25, gender: .male, friends: [yagom, hana])

var encoder = JSONEncoder()

let jsonData = try encoder.encode(eric)
let jsonString = String(data: jsonData, encoding: .utf8)
print(jsonString) 
// "{\"age\":25,\"gender\":\"male\",\"friends\":[{\"age\":20,\"gender\":\"male\",\"friends\":[],\"name\":\"yagom\"},{\"age\":22,\"gender\":\"female\",\"friends\":[{\"age\":20,\"gender\":\"male\",\"friends\":[],\"name\":\"yagom\"}],\"name\":\"hana\"}],\"name\":\"eric\"}"

let decoder = JSONDecoder()
let decoded: Person = try decoder.decode(Person.self, from: jsonData)
print(decoded.name) // eric


NSNumber 브릿징

예상치 못한 결과를 낼 수 있는 NSNumber 브릿징 결과가 수정되었습니다.

// Swift 3

let numberOne = NSNumber(value: Int64.max)

if numberOne is Int16 {
    print("numberOne == Int16")
} else if numberOne is Int64 {
    print("numberOne == Int64")
} // numberOne == Int16

let numberTwo = NSNumber(value: UInt32(777))
if let value = numberTwo as? Int8 {
    print(value)
} // 9

// Swift 4
let numberOne = NSNumber(value: Int64.max)

if numberOne is Int16 {
    print("numberOne == Int16")
} else if numberOne is Int64 {
    print("numberOne == Int64")
} // numberOne == Int64

let numberTwo = NSNumber(value: UInt32(777))
if let value = numberTwo as? Int8 {
    print(value)
} // 아무 출력 없음


그 외 기타 변경사항

* Core Foundation 타입들은 HashableEquatable 프로토콜을 CFHashCFEqual 함수구현을 통해 준수합니다. Swift 3 모드(Swift 3.2 버전)에서도 적용되는 사항입니다. [SR-2388]

* 암시적인 @objc 선언을 이제 더욱 명확히 표현해 주어야 합니다. [SE-0160]

* raw buffer를 슬라이스 한 결과는 더이상 같은 타입으로 반환되지 않습니다. [SE-0138]

* 재정의(override)가 더 완벽하게 지원됩니다. [SR-1529]

* 제네릭 매개변수를 갖는 서브스크립트를 정의할 수 있습니다. [SE-0148]

* 스위프트 타입 시스템이 이제는 하나의 튜플 전달인자를 가지는 함수와 여러 매개변수를 가지는 함수를 구분합니다. [SE-0110]

* 여러 연산자를 수반한 정수형 상수를 정의하는 C 언어의 매크로의 형태를 더 다양하게 임포트 할 수 있습니다. 

* inout 매개변수를 사용하는 reduce 함수가 추가되었습니다. [SE-0171]

* 컬렉션 타입의 두 요소를 서로 바꿔주는 swapAt(_:_:) 메서드가 추가됐습니다. [SE-0173], [SE-0176]


참고문서

Swift CHANGELOG - Swift 4.0






by yagom

facebook : http://www.facebook.com/yagomSoft

facebook group : https://www.facebook.com/groups/yagom/


p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   


↓↓↓ 블로거에게 공감은 큰 힘이 됩니다 ↓↓↓ 


저작자 표시 비영리 변경 금지
신고

'Swift' 카테고리의 다른 글

Swift 4 변경사항  (8) 2017.06.23
Posted by yagom


오늘의 주제

1. 구조체
2. 클래스



안녕하세요, 야곰입니다. 


지난 포스팅에서는 스위프트의 함수와 함께 스위프트에서 제공하는 컬렉션 타입에 대해 알아봤습니다.


2017/01/23 - [Swift] - Swift란 어떤 언어인가?

2017/01/25 - [Swift] - Swift 기초문법 - 변수, 상수, 기초 데이터 타입

2017/02/06 - [Swift] - Swift - 함수, 콜렉션 타입



이번에는 스위프트의 구조체와 클래스에 대해 알아보겠습니다 :)


구조체와 클래스

구조체와 클래스는 프로그래머가 데이터를 용도에 맞게 묶어 표현하고자 할 때 용이합니다. 구조체와 클래스는 프로퍼티와 메서드를 사용하여 구조화된 데이터와 기능을 가질 수 있습니다. 하나의 새로운 사용자정의 데이터 타입을 만들어 주는 것입니다. 


객체지향 프로그래밍 패러다임을 알고 있다면 클래스라는 용어를 들어봤을 겁니다. 객체지향 프로그래밍 패러다임이 아니더라도 데이터를 구조화하여 관리하는 데 구조체를 사용해봤을 겁니다. 스위프트에서는 구조체와 클래스의 모습과 문법이 거의 흡사합니다. 다만, 구조체의 인스턴스는 값 타입이고, 클래스의 인스턴스는 참조 타입이라는 것이 이 둘을 구분하는 가장 큰 차이점입니다. 


이제까지 우리가 알아본 스위프트의 데이터 타입과 열거형은 모두 값 타입니다. 그러나 구조체와 함께 배워볼 클래스는 참조 타입입니다. C 언어와 Objective-C의 포인터와 유사한 개념입니다. 


참고로 스위프트는 참조 타입보다는 값 타입에 친절한 언어입니다.



구조체


구조체는 struct 키워드로 정의합니다.


구조체 명명법



struct [구조체 이름] { [프로퍼티와 메서드들] }


아래에 사람의 기본 정보를 구성하는 구조체를 정의해봤습니다. BasicInformation 이라는 이름으로 정의했으며 이 구조체는 String 타입인 name과 Int 타입인 age라는 저장 프로퍼티를 가집니다.

struct BasicInformation {
    var name: String
    var age: Int
}


구조체 인스턴스의 생성 및 초기화


구조체 정의를 마친 후, 구조체의 인스턴스를 생성하고 초기화하고자 할 때에는 기본적으로 생성되는 멤버와이즈 이니셜라이저를 사용합니다. 구조체에 기본 생성된 이니셜라이저의 매개변수는 구조체의 프로퍼티 이름으로 자동 지정됩니다. 
인스턴스가 생성되고 초기화된 후 프로퍼티 값에 접근하고 싶다면 마침표(.)를 사용하면 됩니다. 구조체를 상수 let으로 선언하면 인스턴스 내부의 프로퍼티 값을 변경할 수 없고, 변수 var로 선언하면 내부의 프로퍼티가 var로 선언된 경우에 값을 변경해줄 수 있습니다. 

// 프로퍼티 이름(name, age)으로 자동 생성된 이니셜라이저를 사용하여 구조체를 생성합니다. var yagomInfo: BasicInformation = BasicInformation(name: "yagom", age: 99) yagomInfo.age = 100 // 변경 가능! yagomInfo.name = "Bear" // 변경 가능! // 프로퍼티 이름(name, age)으로 자동 생성된 이니셜라이저를 사용하여 구조체를 생성합니다. let hanaInfo: BasicInformation = BasicInformation(name: "hana", age: 99) hanaInfo.age = 100 // 변경 불가!


클래스

클래스를 어떻게 정의하고 클래스의 인스턴스를 어떻게 생성하는지 그리고 클래스를 어떻게 활용하는지에 대해 알아보겠습니다. 스위프트의 클래스는 부모클래스가 없더라도 상속 없이 단독으로 정의가 가능합니다. 

클래스 명명법


클래스를 정의할 때에는 class라는 키워드를 사용합니다. 

class [클래스 이름] { 
	[프로퍼티와 메서드들]
} 
클래스를 정의하는 방법은 구조체와 흡사합니다. 다만, 클래스는 상속받을 수 있기 때문에 상 속받을 때에는 클래스 이름 뒤에 콜론(:)을 써주고 부모클래스 이름을 명시합니다. 
class [클래스 이름]: [부모클래스 이름] { 
	[프로퍼티와 메서드들]
}
사람의 기본정보를 프로퍼티로 갖는 클래스를 정의해보겠습니다.

class Person {
    var height: Float = 0.0
    var weight: Float = 0.0
}
위에 정의된 클래스는 Float 타입인 height와 weight 저장 프로퍼티가 있는 Person 클래스입니다. 

클래스 인스턴스의 생성과 초기화


클래스를 정의한 후, 클래스의 인스턴스를 생성하고 초기화하고자 할 때에는 기본적인 이니셜라이저를 사용합니다. 위 코드의 Person 클래스에서는 프로퍼티의 기본값이 지정되어 있으므로 전달인자를 통하여 따로 초깃값을 전달해주지 않아도 됩니다. 
인스턴스가 생성되고 초기화된 후(이니셜라이즈된 후) 프로퍼티 값에 접근하고 싶다면 마침표(.)를 사용하면 됩니다. 구조체와는 다르게 클래스의 인스턴스는 참조 타입이므로 클래스의 인스턴스를 상수 let으로 선언해도 내부 프로퍼티 값을 변경할 수 있습니다. 구조체 코드와 클래스 코드를 비교해보세요.

var yagom: Person = Person() yagom.height = 123.4 yagom.weight = 123.4 let hana: Person = Person() hana.height = 123.4 hana.weight = 123.4


클래스 인스턴스의 소멸


클래스의 인스턴스는 참조 타입이므로 더는 참조할 필요가 없을 때 메모리에서 해제됩니다. 이 과정을 소멸이라고 칭하는데 소멸되기 직전 deinit라는 메서드가 호출됩니다. 클래스 내부에 deinit 메서드를 구현해주면 소멸되기 직전 deinit 메서드가 호출됩니다. 이렇게 호출 되는 deinit 메서드는 디이니셜라이저(Deinitializer)라고 부릅니다. deinit 메서드는 클래스당 하나만 구현할 수 있으며, 매개변수와 반환 값을 가질 수 없습니다. deinit 메서드는 매개변수를 위한 소괄호도 적어주지 않습니다. 또, 프로그래머가 직접 deinit 메서드를 호출할 수도 없습니다. 아래 코드에서 Person 클래스에 구현된 deinit 메서드 를 확인할 수 있습니다.

class Person { var height: Float = 0.0 var weight: Float = 0.0 deinit { print("Person 클래스의 인스턴스가 소멸됩니다.") } } var yagom: Person? = Person() yagom = nil // Person 클래스의 인스턴스가 소멸됩니다.

보통 deinit 메서드에는 인스턴스가 메모리에서 해제되기 직전에 처리할 코드를 넣어줍니다. 예를 들어 인스턴스 소멸 전에 데이터를 저장한다거나 다른 객체에 인스턴스 소멸을 알려야 할 때는 특히 deinit 메서드를 구현해야 합니다. 


구조체와 클래스의 차이

구조체와 클래스는 서로 비슷하거나 같은 점도 많습니다. 다음은 같은 점입니다. 
  • 값을 저장하기 위해 프로퍼티를 정의할 수 있습니다. 
  • 기능 수행을 위해 메서드를 정의할 수 있습니다. 
  • 서브스크립트 문법을 통해 구조체 또는 클래스가 가지는 값(프로퍼티)에 접근하도록 서브스크립트를 정의할 수 있습니다. 
  • 초기화될 때의 상태를 지정하기 위해 이니셜라이저를 정의할 수 있습니다. 
  • 초기구현과 더불어 새로운 기능 추가를 위해 익스텐션을 통해 확장할 수 있습니다. 
  • 특정 기능을 수행하기 위해 특정 프로토콜을 준수할 수 있습니다. 


그러나 확연히 다른 점도 존재합니다. 
  • 구조체는 상속할 수 없습니다.
  • 타입캐스팅은 클래스의 인스턴스에만 허용됩니다.
  • 디이니셜라이저는 클래스의 인스턴스에만 활용할 수 있습니다.
  • 참조 횟수 계산(Reference Counting)은 클래스의 인스턴스에만 적용됩니다. 


구조체와 클래스는 겉보기엔 정의하는 방법도, 인스턴스화하는 방법도, 프로퍼티와 메서드를 갖는다는 점을 비롯해 많은 부분에서 비슷해보입니다. 그러나 이 두 타입을 구분 짓는 가장 큰 차이점은 값 타입과 참조 타입이라는 것입니다. 그래서 참조 횟수 계산은 클래스의 인스턴스에만 해당됩니다. 




스위프트의 기본 데이터 타입은 모두 구조체

public struct String { /// An empty 'String'. public init() }

위의 코드는 스위프트 표준 라이브러리에 포함되어 있는 스위프트의 String 타입의 기본 정의 코드입니다. public은 잠시 제쳐두고, struct 키워드는 익숙하지 않으신가요? 네, 스위 프트의 다른 기본 타입(Bool, Int, Array, Dictionary, Set 등등)도 String 타입과 마찬 가지로 모두 구조체로 구현되어 있습니다. 그렇다는 의미는, 기본 데이터 타입은 모두 값 타입 이라는 뜻입니다. 전달인자를 통해 데이터를 전달하면 모두 값이 복사되어 전달될 뿐, 함수 내부에서 아무리 전달된 값을 변경해도 기존의 변수나 상수에는 전혀 영향을 미치지 못한다는 의미입니다. 이런 점을 더욱 확실히 하기 위해 스위프트의 전달인자는 모두 상수로 취급되어 전달되는 것일지도 모릅니다. 


구조체와 클래스 선택해서 사용하기 

구조체와 클래스는 모두 새로운 데이터 타입을 정의하고 기능을 추가한다는 점에서는 같습니다. 하지만 구조체 인스턴스는 항상 값 타입이고, 클래스 인스턴스는 참조 타입입니다. 그 의미는 생긴 것은 비슷하지만 용도는 다르다는 의미입니다. 프로젝트의 성격에 따라, 데이터의 활용 용도에따라, 특정타입을 구현할 때 구조체와 클래스 둘 중 하나를 선택해서 사용해야 합니다. 
애플은 가이드라인에서 다음 조건 중 하나 이상에 해당된다면 구조체를 사용하기를 권합니다. 
  • 연관된 간단한 값의 집합을 캡슐화 하는 것만이 목적일 때 
  • 캡슐화된 값이 참조되는 것보다 복사되는 것이 합당할 때
  • 구조체에 저장된 프로퍼티가 값 타입이며 참조되는 것보다 복사되는 것이 합당할 때
  • 다른 타입으로부터 상속받거나 자신이 상속될 필요가 없을 때 

구조체로 사용하기에 가장 적합한 예로는 좌표계가 있습니다. x, y 좌표 등을 표현하고 싶을 때 Int 타입으로 x, y 프로퍼티를 가질 수 있으며, 물건의 크기를 표현하고자 할 때는 부동소수 표현인 Double 또는 Float 타입을 사용하여 width, height, depth 등으로 묶어 표현해 줄 수 있습니다. 
이런 몇 가지 상황을 제외하면 클래스로 정의하여 사용합니다. 대다수 사용자정의 데이터 타입은 클래스로 구현할 일이 더 많을 수 있습니다. 

이번에 스위프트의 구조체와 클래스에 대해 알아봤습니다. 다음 포스팅에서는 프로토콜과 익스텐션에 대해 알아보겠습니다. 
다음 번에 또 뵈어요~ 고맙습니다 :D




by yagom

facebook : http://www.facebook.com/yagomSoft

facebook group : https://www.facebook.com/groups/yagom/

twitter : http://www.twitter.com/yagomSoft ( @yagomsoft )

p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   



저작자 표시 비영리 변경 금지
신고

'Swift > 기본문법' 카테고리의 다른 글

스위프트 시작하기  (0) 2017.05.08
Swift - 프로토콜, 익스텐션  (0) 2017.03.07
Swift - 구조체 클래스  (0) 2017.02.28
Swift - 함수, 콜렉션 타입  (0) 2017.02.06
Swift 기초문법 - 변수, 상수, 기초 데이터 타입  (0) 2017.01.25
Swift란 어떤 언어인가?  (0) 2017.01.23
Posted by yagom


What's New in Cocoa Touch

WWDC 2016 - Session 205 



WWDC 2016 세션 205의 주제인 What's New In Cocoa Touch 요약정리입니다.

이 포스트는 세션 205요약 중 네 번째(마지막) 글입니다.


지난 포스팅

  1. 2016/08/13 - [WWDC/WWDC2016] - What's New in Cocoa Touch [Session 205] 1/4
  2. 2016/09/05 - [WWDC/WWDC2016] - What's New in Cocoa Touch [Session 205] 2/4
  3. 2016/12/16 - [WWDC/WWDC2016] - What's New in Cocoa Touch [Session 205] 3/4


이번 포스팅에선 아래 주제를 정리합니다.


# Integrating with iOS

  • Keyboards Extensions
  • Widgets
  • User Notifications
  • CallKit
  • SiriKit
  • Intents Extensions
  • IntentsUI Extensions
  • Intents are Shared
  • iMessage Apps



# Integrating with iOS

iOS와 좀 더 통합할 수 있는 방법을 안내합니다. iOS 10에는 새로운 확장 지점(Extension points) 몇 가지가 추가되었습니다. 바로, 메세지, 시리, 통화(CallKit)입니다.


  • Keyboards Extensions

키보드와 같이 기존에 존재했던 익스텐션도 발전시켰습니다. 키보드 언어 선택 키인 지구본 키를 이제는 키보드 익스텐션에서 사용할 수 있습니다.

사용자가 상호작용하고 있는 언어에 대한 힌트도 제공합니다. 이를 통해 서드파티 익스텐션에서도 수월하게 다양한 언어 지원을 할 수 있습니다.


  • Widgets

위젯의 새로운 디스플레이 모드도 추가되었습니다. 

기존에는 개발자가 위젯사이즈를 조절하였다면 이제는 사용자가 사이즈를 조절할 수 있도록 제공할 수 있습니다.

컴팩트 모드는 위젯의 높이가 고정되어있습니다. 확장 모드는 높이가 가변적입니다. 


새로이 제공되는 API를 통해 이 화면이 어떤 모드로 변경되는지 알 수 있습니다. 또, 개발자가 이 API를 통해 화면의 최대 사이즈를 제공할 수 있으며, 어떤 모드까지 제공할지도 지정할 수 있습니다. 화면을 통해 보여질 정보들을 사용자화 할 수 있게 된 것입니다.


위젯은 잠금화면에서 표시되는 화면이므로 이곳에 표시될 정보를 잘 생각해 보아야 한다는 것입니다. 항상 일관적이고, 프라이버시를 크게 해치지 않은 한도 내에서 정보를 구성해야 할 것입니다.


  • User Notifications

iOS 10의 사용자 알림(user notification)은 완전히 새로워졌습니다.


같은 기능을 새로운 프레임워크에 구현하면서 발전을 시켰습니다. 첫째로 로컬 알림(local notification)과 원격 알림(remote notification)을 통합했습니다. 그렇기 때문에 알림을 관리하기 더욱 쉬워졌습니다. 

또 하나의 발전은, 화면에서 알림이 표시되기 전에 먼저 개발자에게 알려줍니다. 그렇기 때문에 앱에서 스스로 알림을 처리하기 훨씬 용이해졌습니다. 그리고 이런 점은 모든 플랫폼에 동일하게 적용됩니다.

여기에 더불어 두 개의 익스텐션을 추가했습니다. 


첫 번째 익스텐션은 서비스 익스텐션입니다.

서비스 익스텐션은 알림이 화면에 실질적으로 표시되기 전에 부가적인 정보를 삽입할 수 있도록 할 수 있습니다. 그렇기 때문에 알림이 화면에 표시되기 전에 미디어를 삽입하는 등 처리할 일들을 미리 처리할 수 있습니다. 

또 하나의 기능은 단말간 암호화입니다. 서버와 로컬 디바이스에서 모두 암호화 합니다. 그렇기 때문에 서버에서 무엇인가 전달 받으면 로컬 디바이스에서 복호화 해야합니다. 


또 다른 익스텐션은 사용자 알림(user notification) 프레임워크입니다. 알림에 UIView를 포함시킬 수 있습니다. 하지만 그 뷰와 직접적으로 상호작용(interaction)을 할 수는 없습니다. 그렇지만 알림 액션을 사용할 수 있습니다(액션시트 메뉴처럼).


알림에 대해 더 알고 싶다면 [Introduction to Notifications]와 [Advanced Notifications]세션을 참고하세요.


  • CallKit

콜킷(CallKit)또한 iOS 10의 새로운 프레임워크입니다. 주소록(전화번호부, directory) 익스텐션은 수신 통화를 차단하는 것을 설정할 수 있습니다. 수신 전화를 완벽히 제어할 수 있습니다.

전화번호의 신원을 확인하여 화면에 레이블(label)로 표시해 줄 수 있습니다. 전화가 들어올 때 시스템에서 주소록을 찾아보고 해당하는 번호가 없다면 익스텐션을 통해 신원을 확인하게 됩니다.


콜킷의 제일 강력한 기능은 전화제공(call provider) API일 것입니다. 전화제공 API를 통하면 보이스오버 IP 애플리케이션이 마치 시스템 기본 전화기능인 것처럼 사용할 수 있습니다. 보이스 오버 전화를 수신 할 때 기본 전화가 온 것처럼 전체 화면으로 수신을 알릴 수 있으며, 즐겨찾기, 최근통화 목록 등에도 표시됩니다.

시리를 지원할 수도 있으며, 카플레이(CarPlay)를 지원할 수도 있습니다. 잠자기 모드와 블루투스 기능과도 연동됩니다.

콜킷(CallKit)과 관련된 자세한 내용은 [Enhancing Voice Over IP apps with CallKit] 세션을 참고하세요.


  • SiriKit

다음은 시리(Siri)입니다. 여러분들은 아마 모르겠지만, 시리는 상황에 맞게 동작하고 있습니다. 홈버튼을 길게 눌러 시리를 실행할 때와, 시리야 기능일 사용하여 실행할 때와, 카플레이 중에 사용할 때, 손쉬운 사용을 통할 때 등등 각각의 다른 상황에 맞게 시리 스스로 튜닝을 합니다. 이는 매우 복잡한 작업입니다. 인식 경로라던지 분야 또는 국가, 아니면 현재의 환경 따위를 고려해야 하기 때문입니다. 그런데 이것들은 시리 익스텐션을 사용할 때 자동으로 처리해 줄 것입니다.

시리킷에서 제공하는 요청을 표현하는 의도(intent representing the request)를 통해 상호작용 할 수 있습니다.


  • Intents Extensions

시리킷을 통해 자신의 애플리케이션 또는 사용자 별로 사용할 단어들을 지정할 수 있습니다. 의도 익스텐션(intents extension)을 통해 시리와 당신의 애플리케이션이 서로 상호작용 할 수 있습니다. 의도에 따라 시리가 당신의 애플리케이션에 요청을 하고 그에 적절하게 응답할 수 있습니다. 그렇기 때문에 메세지 분야의 애플리케이션이라면 메세지를 보내고자 할 때 시리가 인식할 단어들을 제공해주면 됩니다. 시리가 의도를 파악하여 당신의 애플리케이션과 상호작용 할 것입니다.


  • IntentsUI Extensions

시리킷에 해당하는 두 번째 익스텐션이 있습니다. 의도 UI 익스텐션입니다. 이 익스텐션은 선택사항이지만 시리 화면에서 UI를 표현할 수 있기 때문에 사용자가 더욱 명확히 확인하도록 할 수 있습니다.


  • Intents are Shared



의도 시스템은 꼭 시리에만 국한되는 것은 아닙니다. 의도 시스템은 요청을 표현하는 방법입니다. 물론 이 방법이 시리와 애플리케이션과 소통하는데 사용됩니다. 그렇지만 이 시스템이 어떻게 콜킷과도 관계를 가질 수 있는지 보여드리겠습니다. 즉, 어떻게 애플리케이션의 익스텐션끼리 공유할 수 있는지 볼 수 있다는 뜻입니다. 사용자가 무엇을 하는지 시스템과 정보를 공유해야 합니다. 예를 들어, 메세지 앱이라고 한다면 WWDC 챗 애플리케이션을 통해 메세지를 전송하고 싶다고 말한다면, 연락처 UI에서 연락처에 관한 정보를 자동으로 보여줄 것입니다. 그리고 사용자의 의도를 파악하여 액션 목록에 당신의 애플리케이션을 보여줄 수 있습니다. 게다가 연락처 앱의 기본 메세지 앱으로 당신의 앱을 등록할 수도 있습니다.


  • iMessage Apps

마지막으로 iMessage 앱입니다. 이제 메세지 앱은 하나의 플랫폼이 되었고, 애플은 두 가지 기능을 덧붙였습니다. 하나는 스티커팩이고, 또 하나는 메세지 익스텐션입니다. 


스티커팩은 코드가 필요하지 않습니다. 정적이거나 동적인 이미지들로만 패키지를 구성하고 Xcode를 사용하여 이미지를 메세지 스토어에 배포하기만 하면 됩니다. 


iMessage 앱이 또 새로운 익스텐션을 사용할 수 있습니다. UIKit 기반의 익스텐션이고, 동적으로 스티커 컨텐츠를 생성할 수 있습니다. 이 익스텐션에서는 직접 카메라를 사용할 수도 있죠. 그리고 UI를 간단 모드(compact mode)와 확장 모드(expanded mode)로 구성하고, 메세지 앱에서 사용할 수 있습니다. 익스텐션을 사용하여 메세지 말풍선을 꾸밀수도 있습니다. 



또, 말풍선을 꾸밀 수 있을 뿐만 아니라, 사용자와 상호작용 하도록 만들 수도 있습니다.


iMessage 애플리케이션과 메세지, 스티커 등에 대해서 더 자세히 알고 싶다면 [iMessage Apps and Stickers, Part 1]와 [iMessage Apps and Stickers, Part 2]세션을 참고하세요.









# 간단요약

Keyboards Extensions

  • 사용자의 의도에 따라 자동으로 언어 변경 가능
  • 키보드 익스텐션에서 기본지구본(언어변경 버튼) 사용 가능


Widgets

  • 위젯의 크기를 사용자가 조절할 수 있는 디스플레이 모드 추가(컴팩트, 확장)


User Notifications

  • 로컬알림과 원격알림 통합
  • 알림이 화면에 표시되기 전에 적절한 전처리 가능
  • 알림에 UI화면을 포함할 수 있게됨


CallKit

  • 수신통화를 차단할 수 있음
  • 신원을 확인하여 레이블에 표시해 줄 수 있음
  • 서드파티 전화 애플리케이션을 전화 앱에 통합하여 목록에 표시해 줄 수 있음
  • 서드파티 전화 애플리케이션도 전화 수신 시 기본 전화 앱처럼 화면에 표시됨


SiriKit

  • 사용자의 의도에 따라 적절하게 애플리케이션과 상호작용


Intents Extensions

  • 사용자의 의도에 따라 시리와 애플리케이션 간의 상호작용을 제어


IntentsUI Extensions

  • 사용자의 의도를 명확히 하기 위해서 시리 화면에 UI를 표현할 수 있음


Intents are Shared

  • 사용자의 의도는 여러 방면으로 공유되어 상호작용 함


iMessage Apps

  • 메세지 앱에서 사용될 스티커팩을 만들어 배포할 수 있음
  • 메세지 앱의 말풍선을 꾸밀 수 있으며, 사용자와 상호작용 하도록 구성할 수 있음




* 잘못되거나 부족한 내용이 있다면 덧글 남겨주시면 감사하겠습니다.


by yagom

facebook : http://www.facebook.com/yagomSoft

facebook group : https://www.facebook.com/groups/yagom/


p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   


저작자 표시 비영리 변경 금지
신고
Posted by yagom


What's New in Cocoa Touch

WWDC 2016 - Session 205 



WWDC 2016 세션 205의 주제인 What's New In Cocoa Touch 요약정리입니다.

이 포스트는 세션 205요약 중 세 번째 글입니다.


지난 포스팅

  1. 2016/08/13 - [WWDC/WWDC2016] - What's New in Cocoa Touch [Session 205] 1/4
  2. 2016/09/05 - [WWDC/WWDC2016] - What's New in Cocoa Touch [Session 205] 2/4
이번 포스팅에선 아래 주제를 정리하고, 나머지 주제는 다음 포스팅에서 이어집니다.

# Adopting System Features
  • Opening applications
  • Core Data
  • CloudKit
  • NSUserActivity
  • App Search
  • CoreSpotlight Search API
  • ReplayKit
  • SceneKit
  • Apple Pay



Adopting System Features



iOS 10에서는 굳이 신경써서 도입하지 않아도 알아서 적용될 많은 기능들이 있습니다.

애플리케이션을 향상시킬 새로운 기능들이 있습니다. 이 기능들은 애플리케이션 아키텍쳐를 조금 더 단순화 시켜줄 수도 있습니다.



이는 애플리케이션을 다른 기능들과 더욱 긴밀하게 통합하여 줍니다.


  • Opening applications


그 좋은 예로 먼저 openURL이 있습니다. 컴플리션 핸들러(completion handler)를 통해 URL 열기를 비동기적으로 수행하도록 만들었습니다. 유니버셜 링크(universal link)도 추가했습니다. 만약 예를 들어 SNS 앱에서 유니버셜 링크를 통해 다른 앱을 실행하려고 한다고 생각해 봅시다. 앱이 설치되어 있으면 그 해당 앱이 실행될 것입니다. 그러나 앱이 설치되어있지 않다면, 그것을 확인하여 현재 SNS앱에서 적절히 처리해 줄 수 있도록 해당 앱 설치여부를 확인할 수 있습니다. 이를 통해 컨텐츠를 통합하고 시스템 내부에서 이 애플리케이션들을 적절히 다룰 수 있습니다.

  • Core Data


다음은 코어데이터입니다. 먼저 쿼리 제네레이션(query generation)이라는 것을 살펴봅니다. 분리된 컨텍스트에서 메인UI를 위한 컨텍스트가 존재하고, 이것들은 백그라운드 큐에서 실행하는 것이 일반적입니다. 쿼리 제네레이션을 사용하면 메인UI의 모델을 한 버전에서 또다른 버전으로 변경하는 것을 정확히 제어할 수 있습니다. 이는 기존에 강제적으로 처리했던 것들을 더이상 강제적으로 처리하지 않아도 되는 것을 의미합니다. 왜냐하면 백그라운드 큐에서 무엇인가 변경되고, 메인UI가 새로운 버전의 데이터로 언제 변경될 것인지 정확하게 결정할 수 있게 되기 때문입니다. 이를 통해 코어데이터 코드를 조금 더 단순화 시킬 수 있습니다.

또 다른 기능은 커넥션 풀링에 관한 것입니다. 이제 저장소에서 다중 읽기를 완벽히 지원합니다. 이는 성능향상에 큰 도움이 됩니다. 

또, 코어데티어 관련 툴에 새로운 기능들이 추가되었습니다만, 이는 [What's New in Core Data]에서 더 자세히 알아보시기를 추천드립니다.  

  • CloudKit


데이터를 모델링 하는 방법에는 CloudKit을 이용하는 방법도 있습니다.CloudKit에는 이미 사용자별로 공개 데이터베이스와 개인 데이터베이스를 가질 수 있게 되어있습니다. iOS 10에서는 Record sharing이 추가되었습니다. 그래서 여러 사용자가 하나의 기록에 공동으로 접근할 수 있습니다. 




CloudKit을 사용하는 협업 기반의 애플리케이션은 UI흐름을 다루는 데에는 어려움이 있었습니다.

문서를 공동작업하는데 다른 사람을 어떻게 초대하나요? 정말 안전(secure)한 방법으로 이를 구현할 수 있나요? 그래서 UICloudSharingController를 만들었습니다. 이 뷰 컨트롤러는 UIKit을 통해 화면에 표현할 수 있으며, CloudKit에서 제공하는 recored sharing을 제어하는 새로운 공유 객체를 전달해주기만 하면 됩니다. 



이 뷰 컨트롤러는 초대 흐름을 관리할 수 있는 UI를 자동 생성해줍니다.



또, 초대한 사람들의 목록도 자동으로 생성해 줍니다. 이를 통해 CloudKit을 활용한 협업 기반의 애플리케이션을 조금 더 쉽게 구성할 수 있습니다. [What's New with CloudKit] 세션을 통해 조금 더 자세한 내용을 확인할 수 있습니다.


  • NSUserActivity


NSUserActivity는 애플리케이션의 상태를 캡쳐하는데 사용합니다. 이제껏 핸드오프나 스포트라이트 같은 곳에서 사용해 왔죠.

iOS 10에서는 user activity에 위치도 추가할 수 있습니다. 만약 주소를 다루는 애플리케이션이라면 이 주소에 관한 활동을 사용자에게 표현하고 제공할 수 있습니다. MapKit 아이템을 activity에 추가하여 전달하기만 하면 됩니다. 텍스트 필드의 제안 기능에서 이 주소는 유용하게 사용될 수도 있을 것입니다.

이는 지능과 액티비티 기반의 iOS 10 기능입니다.


  • App Search


NSUserActivity가 사용되는 다른 지점이 있습니다. 바로 검색입니다. iOS 9에서 인덱스된 액티비티가 추가되었습니다. 이 인덱스된 액티비티는 스포트라이트 검색에 노출되었습니다.



이제는 새로운 버튼(Search in App)을 통해 앱 내의 검색으로 바로 진입하여 이어갈 수 있습니다.



이 기능을 구현하려면 먼저 info plist파일에 CoreSpotlightContinuation 키를 추가해 줍니다. 그 후 새로운 UIApplicationDelegate 메서드를 구현해주면 됩니다.


  • CoreSpotlight Search API


iOS 9에서 CoreSpotlight를 통해 앱 내부의 컨텐츠를 인덱싱 할 수 있도록 지원했습니다. 이제는 스포트라이트에서 데이터를 검색할 수 있습니다. 스포트라이트 인덱스를 개방했습니다. 

검색 쿼리를 구성하고 요청을 보내면 애플리케이션의 데이터를 위한 스포트라이트 인덱스를 검색할 수 있습니다. 이를 통해 애플리케이션 내부의 데이터를 시스템에 직접 인덱싱 할 수 있습니다. 이와 관련해서 [Making the Most of Search APIs] 세션을 참고하면 됩니다. 이 세션에서는 continuation과 CoreSpotlight의 검색 등에 대해 자세히 다룹니다.


  • ReplayKit


기존의 ReplayKit은 애플리케이션의 화면을 기록하기 위한 방법이었습니다. 이제 iOS 10에서는 ReplayKit을 사용하여 라이브 스트리밍을 할 수 있습니다. 즉, 생방송이 가능합니다. 


  • SceneKit


SceneKit의 렌더링 엔진이 새로워졌습니다. 물리 기반 렌더링을 수행합니다. iOS 9에 비해 비약적으로 발전했습니다.


  • Apple Pay


사용자 측면에서 애플페이는 어떤 플랫폼을 사용하는지에 상관없이 모든 곳에서 사용할 수 있게 되었습니다. 이제는 iOS와 워치 뿐만 아니라, 웹에서도 애플페이를 사용할 수 있게 되었습니다.



개발자 측면에서 애플페이는 여러가지가 추가되었습니다. 

UIKit 기반의 애플리케이션에서만 지원되었던 애플페이가 많이 확장되었습니다. 

이제는 새로운 자바스크립트 프레임워크를 통해 사파리에서도 애플페이를 지원할 수 있습니다. 이는 SFSafariViewController에서 애플페이를 지원할 수 있게 되었다는 뜻이기도 합니다. 

또, UI가 아닌 코드에서도 애플페이를 사용할 수 있습니다. UI가 아닌 익스텐션에서 사용할 수도 있는데, iMessage 앱의 익스텐션에서 애플페이를 사용하는 것이 좋은 예가 되겠습니다. 이와 관련하여 자세한 내용은 [Apple Pay on the Web]과 [What's New with Wallet and Apple Pay]세션에서 확인해 볼 수 있습니다.




# 간단요약

Opening applications

  • 유니버셜 링크(universal link)를 통한 openURL이 개선되었음 - 비동기 처리, 다른 앱 설치 유무 미리 확인 등


Core Data

  • 쿼리 제네레이션(query generation)기능 추가
  • 동시 처리 성능 향상
  • 툴 발전


CloudKit

  • Record sharing 추가로 여러 사용자가 하나의 기록에 공동으로 접근가능
  • UICloudSharingController을 통해 문서 등의 여러사용자 협업관리를 수월하게 할 수 있음


NSUserActivity

  • NSUserActivity에 위치 정보 추가 가능


App Search

  • 스포트라이트검색의 Search in App 버튼을 통해 앱 내의 검색으로 바로 진입하여 이어갈 수 있음 - CoreSpotlightContinuation


CoreSpotlight Search API

  • 스포트라이트 인덱스를 개방하여 스포트라이트에서 애플리케이션 내부의 컨텐츠 뿐만 아니라 데이터도 검색할 수 있도록 변경


ReplayKit

  • ReplayKit을 사용하여 라이브 스트리밍을 할 수 있음


SceneKit

  • 새로운 렌더링 엔진 - 물리 기반 렌더링
  • iOS 9에 비해 비약적으로 발전


Apple Pay

  • 사용자가 iOS와 워치 뿐만 아니라, 웹에서도 애플페이를 사용할 수 있게 됨
  • 사파리에서도 애플페이를 지원(SFSafariViewController에서 애플페이를 지원가능)
  • UI가 아닌 익스텐션에서도 애플페이 사용가능





* 잘못되거나 부족한 내용이 있다면 덧글 남겨주시면 감사하겠습니다.

* What's New in Cocoa Touch [Session 205]의 나머지 내용은 다음 포스팅에서 이어집니다.


이어지는 다음 포스팅 내용


# Integrating with iOS

  • Keyboards Extensions
  • Widgets
  • User Notifications
  • CallKit
  • SiriKit
  • Intents Extensions
  • IntentsUI Extensions
  • Intents are Shared
  • iMessage Apps

2017/01/04 - [WWDC/WWDC2016] - What's New in Cocoa Touch [Session 205] 3/4



by yagom

facebook : http://www.facebook.com/yagomSoft

facebook group : https://www.facebook.com/groups/yagom/


p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   



저작자 표시 비영리 변경 금지
신고
Posted by yagom


What's New in Cocoa Touch

WWDC 2016 - Session 205 



WWDC 2016 세션 205의 주제인 What's New In Cocoa Touch 요약정리입니다.

이 포스트는 세션 205요약 중 두 번째 글입니다.


지난 포스팅

  1. 2016/08/13 - [WWDC/WWDC2016] - What's New in Cocoa Touch [Session 205] 1/4


이번 포스팅에선 아래 주제를 정리하고, 나머지 주제는 다음 포스팅에서 이어집니다.


# Building better user interfaces

  • Accessibility Inspector
  • Speech Recognition
  • Smarter Text Input
  • Dynamic Type
  • Improved Customization
  • Peek & Pop
  • Refresh Control
  • Collection View
  • Advanced in UIKit Animations



# Building better user interfaces

iOS 10에서 유저와 앱 간의 상호작용(interaction) 그리고 유저 인터페이스(UI)에 대해 생각해 봅니다.

가장 먼저 생각해 볼 것은 모든 사람이 여러분의 애플리케이션과 상호작용을 할 수 있도록 만드는 것입니다.


  • Accessibility Inspector
  • UI 요소의 접근성 프로퍼티를 곧바로 파악하고 연결할 수 있습니다.


    기기 또는 시뮬레이터에서 애플리케이션의 접근성 평가를 확인할 수 있습니다. 이를 통해 접근성 문제를 해결할 힌트를 얻을 수 있습니다.




  • Speech Recognition
  • 새로운 제스쳐와 음성 인식으로도 애플리케이션과 상호작용 할 수 있게 되었습니다. 

    간단한 API로 영어 뿐만 아니라 다른 언어도 인식합니다.


    SFSPeech 클래스를 통해 음성인식을 할 수 있습니다. 

    오디오 파일 또는 실시간 오디오 스트림에도 사용할 수 있습니다. 실시간 음성 분석이 가능하다는 뜻입니다.

    요청(request)를 통해 받아쓰기나 문자열을 통한 인식을 하도록 할 수 있습니다.

    결과(result)를 통해 콜백 받습니다. 쓰기 쉽대요.




  • Smarter Text Input
  • 텍스트 필드에 컨텐츠의 종류에 대해 정보를 추가할 수 있습니다. 이를 통해 빠른 입력을 지능적으로 제시할 수 있도록 할 수 있죠.

    예를 들어, 위치에 관련된 텍스트 필드라면 빠른 입력에서 주소를 볼 수 있습니다. 

    이메일, 전화번호, 신용카드 번호 등의 컨텐츠 종류를 표현할 수 있습니다.



  • Dynamic Type
  • iOS 7에서 추가된 동적 타입(dynamic type)의 기능이 iOS 10에서 더 추가되었습니다.

    동적 타입을 위해 컨텐츠 사이즈 카테고리를 만들었습니다.

    iOS 10 이전에는 컨텐츠 사이즈 카테고리는 UIApplication의 프로퍼티였습니다.

    사용자가 컨텐츠 사이즈를 변경하거나 하면 그에 대응하기 위해 노티피케이션을 수신하고 있어야 했습니다. 그렇지만 이제는 하나의 특성(trait)으로 통합되었기 때문에 노티피케이션을 수신할 필요가 없습니다.

    이제는 동적 타입을 익스텐션으로 사용이 가능합니다. 



    iOS 10에서는 UIKit에 이전부터 존재하던 관련 요소들에도 동적 타입을 적용하였습니다.

    텍스트와 관련된 UI 요소인 텍스트 필드, 텍스트 뷰, 레이블 등이 컨텐츠 사이즈 카테고리를 위한 글꼴 적용을 사용할 수 있게 되었습니다.



  • Improved Customization
  • UIKit에 사용자화(커스터마이징)이 대폭 추가되었습니다. 바 버튼 아이템이 그 좋은 예가 되겠습니다.

    탭바 아이템에 배치 색상을 사용자화 할 수 있으며, 텍스트에 속성(attributes)를 추가할 수 있습니다. 선택되지 않은 상태의 색상을 변경할 수도 있습니다.



  • Peek & Pop
  • 웹뷰에도 또 다른 방법으로 사용자화가 가능하게 되었습니다.

    3D 터치를 이용한 Peek & Pop 기능을 뷰컨트롤러를 위한 UIKit의 간단한 API만으로 추가할 수 있습니다. WKWebView에도 이런 기능이 추가되었습니다.

    웹뷰에서도 Peek & Pop을 좀 더 쉽게 제어할 수 있습니다. 다시 말해서 Peek 할 때 사용하는 뷰 컨트롤러를 사용자화 할 수 있습니다. Peek을 하면 미리보기를 할 수 있고, Pop을 하면 여러분의 앱 안에서 무슨 처리를 할 지 결정할 수 있습니다. 웹뷰 클래스의 델리게이트 메서드를 통해 이런 일들을 처리할 수 있습니다.

    UIKit에서 Peek & Pop 동작을 할 때, 블러 효과같은 기본적인 효과 외에도 사용자가 Peek 하려는 것을 감지하고, 어떤 행위를 할 것인지 감지해서 여러분만의 전환효과를 줄 수 있습니다. 



  • Refresh Control
  • Refresh Control을 UIScrollView와 그 자식 클래스에서 모두 사용할 수 있습니다. 즉, UITableView에만 제공되었던 기본적인 refresh control을 콜렉션 뷰를 포함한 여러 스크롤 환경에서 사용할 수 있게 되었다는 뜻입니다.



  • Collection View
  • 작년에는 콜렉션뷰의 flow layout의 새로운 모드가 생겼습니다. 자동 모드를 사용하면 더이상 셀의 크기를 예상하기 위하여 계산하지 않아도 됩니다. 또한, 스크롤뷰의 페이징 기능을 사용할 때 셀을 재정렬(reordering)하는 기능을 구현하였습니다.

    올해는 더욱 부드러운 스크롤을 위해 새로운 기능이 추가되었습니다.

    만약 셀에 복잡한 정보를 나타내야 할 때에는 빠른 스크롤을 하게된다면 버벅일 수 있었는데, 이는 사용자 경험으로 좋지 못하죠.

    그래서 cell prefetching 기능을 추가했습니다. 셀이 화면에 나타나기 전에 셀과 데이터를 미리 로드해 둘 수 있습니다. 물론 언제 어떻게 불러올지는 자동으로 모두 처리됩니다.  

    iOS 10으로 빌드한다면 셀을 미리 불러오는 것들은 자동으로 처리될 것입니다. 그렇지만 데이터를 미리 로드해 오는 것은 새로운 델리게이트 프로토콜 메서드를 통해 구현해 주어야 합니다.

    (테이블뷰에도 이런 기능이 추가되었습니다)


  • Advanced in UIKit Animations
  • UIViewPropertyAnimator라고 불리는 애니메이션 관련 기능이 추가되었습니다. 이는 새로운 애니메이션 API입니다.

    취소할 수 있고, 되감을 수 있으며, 타이밍을 정할 수 있으며, 완벽히 동적으로 동작합니다.



    애니메이션을 동영상의 타임라인처럼 관리를 할 수 있습니다. 

    타이밍과 동작시간을 매개변수로 전달하여 애니메이션에 추가할 수 있습니다.

    애니메이션 객체가 애니메이션을 표현하게 됩니다. 동작 중에 다양한 변화를 추가하거나 수정할 수 있습니다.

    뷰컨트롤러 작동 시스템에 완벽하게 녹아들어가 있습니다.

    이 새로운 애니메이션 기능의 강력한 포인트는 애니메이션을 사용자와 직접 상호작용 할 수 있도록 구현할 수 있다는 점입니다.



    # 간단요약

    Accessibility Inspector

    • 내 앱에 사용자 접근성 사용 기능이 어떤 것이 적용되어 있는지를 개발자가 더욱 편리하게 확인할 수 있는 기능이 추가됨


    Speech Recognition

    • 오디오 또는 실시간 입력으로도 음성인식 기능을 사용할 수 있음
    • 영어 외에 다른 나라 언어도 많이 지원함


    Smarter Text Input

    • 텍스트필드에 입력될 데이터가 어떤 종류인지 지정해두면 사용자가 원하는 데이터를 더 편리하게 입력할 수 있도록 도와줌


    Dynamic Type

    • 컨텐츠 사이즈 카테고리에 따라 글꼴 등을 알아서 표현해 줌


    Improved Customization

    • UIKit에 사용자화(커스터마이징) 할 수 있는 영역이 대폭 추가됨 (바 버튼 아이템의 여러 속성 등)


    Peek & Pop

    • 3D 터치를 통한 미리보기 기능의 전환효과를 사용자화 할 수 있음


    Refresh Control

    • Refresh Control을 테이블뷰 외에도 UIScrollView의 모든 자식클래스에서 사용할 수 있게 됨


    Collection View

    • 페이징 할 때 등 flow layout이 개선됨
    • 데이터를 미리 불러와 두고 처리해 둠으로써 콜렉션뷰를 조금 더 쾌적하게 사용할 수 있도록 개선


    Advanced in UIKit Animations

    • 애니메이션을 손쉽고 유려하게 다룰 수 있는 많은 기능이 추가됨
    • 애니메이션 표현 정보를 객체로 다룰 수 있게 되었고 손쉽게 사용자와 상호작용(interaction) 할 수 있음






    * 잘못되거나 부족한 내용이 있다면 덧글 남겨주시면 감사하겠습니다.
    * What's New in Cocoa Touch [Session 205]의 나머지 내용은 다음 포스팅에서 이어집니다.

    이어지는 다음(그리고 그 다음) 포스팅 내용

    # Adopting system features

    # Integrating with iOS


    2016/12/16 - [WWDC/WWDC2016] - What's New in Cocoa Touch [Session 205] 3/4

    2017/01/04 - [WWDC/WWDC2016] - What's New in Cocoa Touch [Session 205] 3/4





    by yagom

    facebook : http://www.facebook.com/yagomSoft

    facebook group : https://www.facebook.com/groups/yagom/


    p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

    RSS Feed 받기   



    저작자 표시 비영리 변경 금지
    신고
    Posted by yagom


    What's New in Cocoa Touch

    WWDC 2016 - Session 205 


    WWDC 2016 세션 205의 주제인 What's New In Cocoa Touch 요약정리입니다.

    이 포스트는 세션 205요약 중 첫 번째 글입니다.

    이번 포스팅에선 아래 주제를 정리하고, 나머지 주제는 다음 포스팅에서 이어집니다.


    # What's Not New in Cocoa Touch

    • Adaptivity
    • Advanced Touch Input
    • Keyboard Support

    # Core technologies

    • Swift 3
    • Grand Central Dispatch
    • Foundation
    • UIPasteboard
    • Wide Color
    • Image Renderer
    • Asset Management






    # What's Not New in Cocoa Touch

    작년에 변경된 코어한 내용들에 대한 소개입니다.



    작년에 3D Touch를 탑재한 iPhone 6s를 출시. 12.9인치 및 9.7인치 iPad Pro 출시. 애플 펜슬 및 스마트 키보드 출시.

    이런 제품들은 새로운 기능들을 앱에 유려하게 넣을 수 있도록 기능이 추가되었습니다.


  • Adaptivity
    • 2년 전 사이즈 클래스 기반의 반응형 기술을 소개했습니다. iPhone은 Compact 사이즈, iPad는 Regular 사이즈입니다. 그러면 iPad Pro는 Gigantic(거대)사이즈를 적용해야 할까요?



      당연히 아니겠죠. 사이즈 클래스가 중요해진 만큼 그를 지원하는 많은 툴들이 보강되었습니다. 인터페이스 빌더를 비롯하여 오토 레이아웃과 에셋 카탈로그까지 프레임워크 전반적으로 새로운 기능들이 보강되었습니다. 


    • Advanced Touch Input
      • iPad Air 2와 iPad Pro는 화면 재생 빈도(screen refresh rate)보다 빠르게 터치 입력 스캐닝을 120 HZ로 할 수 있습니다.

        방향과 각도도 파악할 수 있고, 더 정확한 위치와 압력을 인식할 수 있는 애플 펜슬응 사용할 수 있습니다. iPhone 6s에서는 이를 3D Touch 기술을 이용하여 인식할 수 있습니다.

        위 기능들을 사용하기 위해 iOS 9 및 iOS 9.1에서 새로운 API를 사용할 수 있었습니다.



        • Keyboard Support

        키보드 단축키 API는 iOS 7 부터 사용할 수 있었지만, iOS 9 부터는 단축키를 화면에 자동으로 표시할 수 있는 기능이 추가되었기 때문에 더욱 중요해 졌다고 할 수 있습니다. 커맨드 키를 계속 누르고 있으면 자동으로 단축키를 화면에 표시해줍니다.


        # What's New in Cocoa Touch

        이번 iOS 10에 변경된 내용들에 대한 소개입니다.



        Core technologies

        이번 iOS 10에 변경된 중요한 내용들에 대한 소개입니다.



        • Swift 3


        Before - Swift 2.2


        After - Swift 3.0

        거의 모든 API가 새로워졌습니다.
        Objective-C의 문법에서 Swift의 문법으로 변환하는 규칙을 변경하였습니다. 첫 번째 파라메터 이름을 사용하게 변경하여 좀 더 명확하게 표현할 수 있으며, (UIColor의 blackColor가 black으로 변경된 것처럼) 타입 메서드 이름이 타입 이름과 중복되던 현상을 줄일 수 있습니다.

        코어 그래픽(Core graphics) 메서드도 좀 더 쓰기 용이하게 변경되었습니다.

        GCD(Grand central dispatch)가 이제 완전한 객체형 API로 변경되었습니다.

        • Grand Central Dispatch

        개인 큐(private queue)를 생성할 수 있습니다. 큐 작업 아이템이 동기로 실행될 때, 오토 릴리즈 풀에 있는 각각의 작업 아이템을 래핑할 수 있도록 큐를 설정할 수 있습니다.  


        • Foundation

        Foundation도 스위프트의 발전 사항을 많이 적용하였습니다. 많은 클래스에서 NS 접두어를 없애고 새로운 기능을 추가했으며, Foundation API에 값 타입(Value types)를 더 추가했습니다.


        길이나 측량 단위도 모두 지원합니다. 

        AP 601 날짜 형식(Date format)도 추가했습니다.

        NSDateInterval을 통해 날짜를 계산하기 더 편리해졌습니다.

        • UIPasteboard

        UIPasteboard API를 사용하여 여러분의 앱에서 Mac과 iOS 기기 간에 복사/붙여넣기 영역을 공유할 수 있습니다. 

        한 가지 알아두어야 할 점이 있습니다. 큰 이미지 등과 같이 매우 큰 에셋을 가져오려면 1~2초 정도 걸릴 수 있습니다. 이를 피하려면, 그 데이터가 필요한지 아닌지를 먼저 판단해 주어야 합니다. API를 통해 URL, 이미지, 색상 등의 정보가 있는지 먼저 확인해 볼 수 있습니다. 


        pasteboard로 어떤 정보들을 실어 보낼지 제어할 수 있습니다. 데이터를 보호할 수도 있고, 만료시각을 설정할 수도 있습니다.


        • Wide Color

        iMac의 5K 화면 및 iPad Pro 9.7 인치의 하드웨어에 적용될 수 있는 기능입니다. 기존 하드웨어에서는 표현할 수 없었던 색상을 표현할 수 있습니다.

        색상을 표현하는 방법을 변경하고 있습니다. iOS 기기는 sRGB 색상을 사용했습니다. 이제는 확장된 sRGB(extended sRGB)를 사용합니다.

        iOS 10 API를 사용하여 확장된 색상을 사용할 수 있습니다.



        확장된 색상을 사용하는 그 첫 번째는 UIImageView입니다.  단순히 UIImageView를 사용하는 것으로도 광역 색상(wide color)을 사용합니다. 사실 iOS 9.3부터 그렇게 관리되어왔습니다. 



        기존에 존재하던 이니셜라이저 외(init(red: green: blue: alpha:))에 새로 하나(init(displayP3Red: green: blue: alpha:))가 추가되었습니다. 

        상단의 이니셜라이저로 확장된 sRGB 색상을 표현할 수 있습니다.

        당신이 광역 색상(wide color) 스펙으로 displayP3를 사용하려면 하단의 displayP3 이니셜라저를 사용하면 됩니다. 따로 색 공간(color space)를 관리하는 클래스는 없습니다.


        • Image Renderer

        이제까지 여러분은 이미지 UIGraphicsBeginImageContext를 사용하여 이미지 랜더링을 하고 있었습니다. 이런 방식은 이미지를 화면 밖에서 랜더링 한다는 문제점이 있었습니다.

        이 방법은 32비트 sRGB만 사용할 수 있습니다. 확장이 용이하지 못하고 좋지 못한 API의 형태였습니다.



        그래서 UIGraphicsRenderer 클래스를 만들었습니다. 

        이 클래스를 사용하면 9.7인치 iPad에서는 광역 색상 컨텍스를, 다른 기기에서는 기존 색상 컨텍스를 자동으로 판단하여 사용합니다. 

        또한, 블럭을 기반으로 설계되어 사용하기 쉽습니다. 또, 객체 기반 API로 설계하였기 때문에 이미지와 PDF를 위한 클래스를 늘렸습니다.

        또 중요한 점은 이 클래스는 컨텍스트의 활동시간(lifetime)를 관리합니다. 메모리 관리가 훨씬 용이해 졌다는 뜻이겠죠.

        • Asset Management

        이미지 에셋 카탈록에도 새로운 기능이 추가되었습니다. 에셋 카탈록이 광역 색상을 지원하고, 좌에서 우, 우에서 좌의 표현, 그리고 이미지 압축을 관리합니다. UIKit 시스템에 포함되어 있습니다.


        여러분의 애플리케이션에 광역 색상 에셋을 포함시켰을 때, 광역 색상을 사용하지 않는 기기에는 배포되지 않도록 구성할 수 있습니다. 또, 그런 기기로 배포하기 위해 sRGB로 자동으로 변형하여 주게됩니다. 이는 App Thinning 기능과 호환되어 적절한 에셋이 적용될 수 있도록 하여 앱을 더욱 가볍게 만들어 줄 수 있습니다.


        기기에 따라 이미지를 손실압축 할 수 있습니다. 용량과 화질 사이의 최상의 타협점을 찾아냅니다. 이 또한 App Thinning 기능과 호환됩니다.


        이미지마다 왼쪽읽기 및 오른쪽읽기에 따라서 이미지가 반전 되어야 하는지 아닌지를 지정할 수 있습니다.




        * 잘못되거나 부족한 내용이 있다면 덧글 남겨주시면 감사하겠습니다.
        * What's New in Cocoa Touch [Session 205]의 나머지 내용은 다음 포스팅에서 이어집니다.

        이어지는 다음(그리고 그 다음) 포스팅 내용

        # Building better user interfaces

        # Adopting system features

        # Integrating with iOS


        2016/09/05 - [WWDC/WWDC2016] - What's New in Cocoa Touch [Session 205] 2/4

        2016/12/16 - [WWDC/WWDC2016] - What's New in Cocoa Touch [Session 205] 3/4

        2017/01/04 - [WWDC/WWDC2016] - What's New in Cocoa Touch [Session 205] 3/4




        by yagom

        facebook : http://www.facebook.com/yagomSoft

        facebook group : https://www.facebook.com/groups/yagom/


        p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

        RSS Feed 받기   

        저작자 표시 비영리 변경 금지
        신고
        Posted by yagom



        Objective-C의 기능 추가

        1. Nullability annotations 
        2. Generics 



        안녕하세요 야곰입니다 :)

        Swift 2.0이 오픈소스화 되면서 관심이 많이 쏠리고 있습니다.


        그러나 기존 Objective-C 프로그래머들 사이에서는 Swift에 따라 변화되는 다양한 모습들이 부담으로 다가오기도 합니다. Swift 언어 문법과 기능들에 더 잘 맞춰주기 위하여 기존의 API들이 변경되기도 하고, Objective-C의 문법적 기능들과 키워드들이 몇몇가지 추가되기도 했습니다. 그에대해 간략히 살펴보는 시간을 가져보도록 할게요.


        # 해당내용은 2015년 6월 말에 작성된 내용으로, 애플에 의해 추후 변동의 여지가 충분히 있음을 미리 알립니다.


        # Nullability

        Swift는 지난 포스팅에 말씀드렸듯 자료형에 굉장히 민감합니다. 더불어 nil에 대해서 Objective-C와 완전히 다른 대응체계를 가졌죠. Swift 에서는 nil이란 녀석에도 굉장히 민감합니다. 그래서 그런 Swift의 특성에 맞도록 Objective-C의 기능이 추가되었습니다. 바로 nullability라는 기능인데요, 한 번 살펴보죠. Nullability 기능은 Xcode 6.3 / Swift 1.2 버전부터 정식 지원합니다.


        weakstrong, __weak__strong 이라는 키워드 기억하시나요? ARC 때문에 생겨난 새로운 키워드였죠. 이와 쓰이는 위치가 비슷합니다. (예를 든 것일뿐 weak와 strong 키워드와는 전혀 상관이 없습니다)


        Nullability 기능으로 새로 생겨난 키워드는 nullable, nonnull, null_unspecifiednull_resettable 등입니다.


        - nullable : 해당 항목이 null일 수 있다. 즉, Swift의 옵셔널 [?] 항목입니다.

        - nonnull: 해당 항목이 null일 수 없다. 즉, Swift의 논옵셔널 항목입니다.

        - null_unspecified : 해당 항목의 null 여부가 지정되어있지 않다. 즉, Swift의 암시적 추출 옵셔널 형식 [!] 항목입니다.

        - null_resettable : 해당 프로퍼티가 기본값을 가지고 있어 nil일 수 없을 경우에 사용합니다.

                                       즉, nil을 할당하면 즉기 기본값으로 초기화되는 프로퍼티에 사용할 수 있습니다. 

                                       Swift에서는 암시적 추출 옵셔널 형식 [!] 으로 표현됩니다.


        * nullability 키워드를 별도로 지정하지 않는 경우 null_unspecified가 기본입니다.

        ** nullable, nonnull, null_unspecified는 Objective-C 프로퍼티와 메소드, C와 블럭 포인터 등 

             전반적으로 모두 사용가능하지만, null_resettable은 Objective-C 프로퍼티에만 사용 가능합니다.


        일단 메소드에 쓰이는 예를 살펴보죠. UIViewController의 한 메소드입니다. Swift 코드와 Objective-C 코드를 살펴보면 기존의 API와 다르게 nullability 관련 키워드가 Swift의 옵셔널 형식에 맞게 반환자료형 또는 전달자료형 뒤에 삽입되어 있음을 확인할 수 있습니다.


        [ nonnullnullable의 API 적용 예 ]

        [ null_unspecifed의 프로퍼티 적용 예 ]


        위에서 nullability 관련 키워드를 설정해 주지 않는 경우 기본적으로 null_unspecified가 기본값으로 적용된다고 말씀드렸는데, 기본값을 변경할 수 있는 메크로가 존재합니다. NS_ASSUME_NONNULL_BEGIN과 NS_ASSUME_NONNULL_END. 이렇게 한 쌍으로 존재합니다. 저 한 쌍의 매크로 안쪽에 해당하는 항목들은 기본적으로 nonnull 옵션이 적용됩니다.

        스크린샷을 보시면 실제로 Swift에서 어떻게 적용이 되는지도 확인하실 수 있을겁니다.



        [ Objective-C 코드에서 NS_ASSUME_NONNULL_BEGIN과 NS_ASSUME_NONNULL_END의 적용 예 ]



        [ 위의 Objective-C 코드로 작성된 내용을 Swift 코드에서 확인 ]



        null_resttable에 관련된 프로퍼티를 찾아보았으나 찾지 못했습니다. 애플이 제공한 null_resettable에 관한 문서설명에는 아래 스크린샷과 같이 나와있지만 실제 tintColor는 null_resttable이 아니었습니다 :) 참고로 알아두시면 될 것 같습니다.



        null_resttable에 대한 설명 ]




        # Generics


        Objective-C에서 제네릭이 추가되었다고하여 찾아보았는데, 아마도 Swift의 콜렉션 타입(배열, 딕셔너리, 세트)를 위해 반영이 된 것 같습니다. Objective-C 에서는 배열(NSArray), 딕셔너리(NSDictionary), 세트(NSSet)에 자료형에 상관없이 한 콜렉션에 여러가지 객체형태를 넣어줄 수 있었죠. 즉, myArray라는 NSArray에 문자열도, 숫자도, 뷰 객체도 한 번에 들어갈 수 있었다는 이야기입니다. 그러나 Swift에서는 하나의 콜렉션에는 하나의 자료형밖에 담지 못합니다. Array도, Dictionary도, Set도 전부 담게되는 자료형을 명시해 주고, 그 자료형과 맞지 않으면 넣을 수 없었습니다. 이런 차이를 극복하기 위해 Objective-C에 기능을 추가했군요. 저는 Objective-C의 콜렉션이 자료형과 상관없이 넣을 수 있어서 참 강력하다고 생각했는데, 개인적으로는 아쉽습니다. Objective-C의 generics은 Xcode 7 / Swift 2.0 부터 지원합니다.


        스크린샷을 보시면 어떻게 상호 호환되는지 확인해 보실 수 있습니다. __kindof 키워드는 그 클래스와 하위 클래스까지 호환됨을 의미합니다. 실질적으로 Swift의 코드에 미치는 영향은 없습니다.


        [ Objective-C 코드에서 Generics의 적용 예 ]


        [ 위의 Objective-C 코드로 작성된 내용을 Swift 코드에서 확인 ]



        애플이 단지 Swift를 밀어주기 위해 Objective-C를 변경 하는 것인지, 아니면 두 언어의 상생을 위하여 Objective-C를 조금 희생시키는 것인지는 두고봐야 할 것 같습니다.
         

        # 오늘은 6.25 한국전쟁 발발일입니다. 오늘만이라도 뼈아픈 민족상잔의 비극을 잊지않고 되돌아 보는 시간이 되면 좋겠습니다.

        [역사를 잊은 민족에게 미래는 없습니다]

        by yagom

        facebook : http://fb.yagom.net

        facebook group : https://www.facebook.com/groups/yagom/

        twitter : http://twitter.yagom.net ( @yagomsoft )

        p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

        RSS Feed 받기   



        저작자 표시 비영리 변경 금지
        신고
        Posted by yagom
        iOS6 개발자 버전으로 업데이트 하였습니다.

        그런데  새로운 지도에 독도는 없습니다.

        다케시마가 있을 뿐...

        지도의 데이터를 일본 회사에서 가져오는데, 그 일본 회사에서 독도를 다케시마로 표기했다는 이야기가 있습니다.

        애플에 잘못된 점을 알려서 수정을 해야 할 것입니다.

        그래서 저도 문제 리포트를 보냈습니다.

        iOS6의 새로운 지도앱을 실행하여 독도가 아닌 '竹島'로 검색합니다. 타케싀마...
        (일본어 키보드 Romaji를 추가하여 takeshima(竹島)를 입력해 주시면 됩니다.
        그 후 핀이 나타나면 눌러서 문제 리포트를 선택.


        정보가 올바르지 않음


        거기에 수정된 정보를 입력합니다.

        독도(Dokdo)

        경상북도 울릉군 울릉읍 독도리
        Dokdo-ri, Uleung-eup, Uleung-gun, Geyongbuk, Republic of Korea


        보내줍시다.

        잘못된 정보를 고칩시다...!

        여러분 동참해 주세요~! 
        저작자 표시 비영리 변경 금지
        신고

        'yagom's life' 카테고리의 다른 글

        iOS 6 siri의 반응들 :D  (2) 2012.06.14
        iOS6 지도의 다케시마...  (4) 2012.06.14
        맥과이어 휠 세정제  (7) 2011.12.06
        정체불명 닭요리  (6) 2011.11.17
        Posted by yagom


        티스토리 툴바