'extension'에 해당되는 글 3건

  1. 2017.07.20 익스텐션
  2. 2017.03.07 Swift - 프로토콜, 익스텐션
  3. 2017.01.02 What's New in Cocoa Touch [Session 205] 3/4

익스텐션

Swift/기본문법 2017.07.20 15:59

익스텐션

익스텐션(Extension) 은 스위프트의 강력한 기능 중 하나입니다. 익스텐션은 구조체, 클래스, 열거형, 프로토콜 타입에 새로운 기능을 추가 할 수 있는 기능입니다. 

기능을 추가하려는 타입의 구현된 소스 코드를 알지 못하거나 볼 수 없다 해도, 타입만 알고 있다면 그 타입의 기능을 확장할 수도 있습니다.


스위프트의 익스텐션이 타입에 추가할 수 있는 기능

  • 연산 타입 프로퍼티 / 연산 인스턴스 프로퍼티 
  • 타입 메서드 / 인스턴스 메서드
  • 이니셜라이저
  • 서브스크립트 
  • 중첩 타입
  • 특정 프로토콜을 준수할 수 있도록 기능 추가 


익스텐션은 타입에 새로운 기능을 추가할 수는 있지만, 기존에 존재하는 기능을 재정의 할 수는 없습니다.


클래스의 상속과 익스텐션을 비교해보겠습니다. 이 둘은 비슷해보이지만 실제 성격은 많이 다릅니다. 

클래스의 상속은 클래스 타입에서만 가능하지만 익스텐션은 구조체, 클래스, 프로토콜 등에 적용이 가능합니다. 또 클래스의 상속은 특정 타입을 물려받아 하나의 새로운 타입을 정의하고 추가 기능을 구현하는 수직 확장이지만, 익스텐션은 기존의 타입에 기능을 추가하는 수평 확장입니다. 또, 상속을 받으면 기존 기능을 재정의할 수 있지만, 익스텐션은 재정의할 수 없다는 것도 큰 차이 중 하나입니다. 상황과 용도에 맞게 상속과 익스텐션을 선택하여 사용하면 됩니다. 

 

 상속

익스텐션 

확장 

수직확장 

수평확장 

사용 

클래스 타입 

클래스, 구조체, 프로토콜, 제네릭 등 모든 타입 

재정의 

가능 

불가능 


익스텐션을 사용하는 대신 원래 타입을 정의한 소스에 기능을 추가하는 방법도 있겠지만, 외부 라이브러리나 프레임워크를 가져다 썼다면 원본 소스를 수정하지 못합니다. 이처럼 외부에서 가져온 타입에 내가 원하는 기능을 추가하고자 할 때 익스텐션을 사용합니다. 따로 상속을 받지 않아도 되며, 구조체와 열거형에도 기능을 추가할 수 있으므로 익스텐션은 매우 편리한 기능입니다. 

익스텐션은 모든 타입에 적용할 수 있습니다. 모든 타입이라 함은 구조체, 열거형, 클래스, 프로토콜, 제네릭 타입 등을 뜻합니다. 즉, 익스텐션을 통해 모든 타입에 연산 프로퍼티, 메서드, 이니셜라이저, 서브스크립트, 중첩 데이터 타입 등을 추가할 수 있습니다.

더불어 익스텐션은 프로토콜과 함께 사용하면 굉장히 강력한 기능을 선사합니다. 이 부분은 프로토콜 중심 프로그래밍(Protocol Oriented Programming)에 대해 더 알아보면 좋습니다.


소스코드


정의 문법

extension 키워드를 사용하여 정의합니다.

extension 확장할 타입 이름 {
    /* 타입에 추가될 새로운 기능 구현 */
}


익스텐션은 기존에 존재하는 타입이 추가적으로 다른 프로토콜을 채택할 수 있도록 확장할 수도 있습니다. 이런 경우에는 클래스나 구조체에서 사용하던 것과 똑같은 방법으로 프로토콜 이름을 나열해줍니다.

extension 확장할 타입 이름: 프로토콜1, 프로토콜2, 프로토콜3... {
    /* 프로토콜 요구사항 구현 */
}


스위프트 라이브러리를 살펴보면 실제로 익스텐션이 굉장히 많이 사용되고 있음을 알 수 있습니다. Double 타입에는 수많은 프로퍼티와 메서드, 이니셜라이저가 정의되어 있으며 수많은 프로토콜을 채택하고 있을 것이라고 예상되지만, 실제로 Double 타입의 정의를 살펴보면 그 모든것이 다 정의되어 있지는 않습니다. 

그러면 Double 타입이 채택하고 준수해야 하는 수많은 프로토콜은 어디로 갔을까요? 어디에서 채택하고 어디에서 준수하도록 정의되어 있을까요? 당연히 답은 익스텐션입니다. 이처럼 스위프트 표준 라이브러리 타입의 기능은 대부분 익스텐션으로 구현되어 있습니다. Double 외에도 다른 타입들의 정의와 익스텐션을 찾아보면 더 많은 예를 보실 수 있습니다. 꼭 한 번 찾아보세요! 


익스텐션 구현

연산 프로퍼티 추가

extension Int {
    var isEven: Bool {
        return self % 2 == 0
    }
    var isOdd: Bool {
        return self % 2 == 1
    }
}

print(1.isEven) // false
print(2.isEven) // true
print(1.isOdd)  // true
print(2.isOdd)  // false

var number: Int = 3
print(number.isEven) // false
print(number.isOdd) // true

number = 2
print(number.isEven) // true
print(number.isOdd) // false

위 코드의 익스텐션은 Int 타입에 두 개의 연산 프로퍼티를 추가한 것입니다. Int 타입의 인스턴스가 홀수인지 짝수인지 판별하여 Bool 타입으로 알려주는 연산 프로퍼티입니다. 익스텐션으로 Int 타입에 추가해준 연산 프로퍼티는 Int 타입의 어떤 인스턴스에도 사용이 가능합니다. 위의 코드처럼 인스턴스 연산 프로퍼티를 추가할 수도 있으며, static 키워드를 사용하여 타입 연산 프로퍼티도 추가할 수 있습니다. 


메서드 추가

extension Int {
    func multiply(by n: Int) -> Int {
        return self * n
    }
}
print(3.multiply(by: 2))  // 6
print(4.multiply(by: 5))  // 20

number = 3
print(number.multiply(by: 2))   // 6
print(number.multiply(by: 3))   // 9

위 코드의 익스텐션을 통해 Int 타입에 인스턴스 메서드multiply(by:) 메서드를 추가했습니다. 여러 기능을 여러 익스텐션 블록으로 나눠서 구현해도 전혀 문제가 없습니다. 관련된 기능별로 하나의 익스텐션 블록에 묶어주는 것도 좋습니다. 


이니셜라이저 추가

extension String {
    init(int: Int) {
        self = "\(int)"
    }
    
    init(double: Double) {
        self = "\(double)"
    }
}

let stringFromInt: String = String(int: 100) 
// "100"

let stringFromDouble: String = String(double: 100.0)    
// "100.0"

인스턴스를 초기화(이니셜라이즈)할 때 인스턴스 초기화에 필요한 다양한 데이터를 전달받을 수 있도록 여러 종류의 이니셜라이저를 만들 수 있습니다. 타입의 정의부에 이니셜라이저를 추가하지 않더라도 익스텐션을 통해 이니셜라이저를 추가할 수 있습니다. 

하지만 익스텐션으로 클래스 타입에 편의 이니셜라이저는 추가할 수 있지만, 지정 이니셜라이저는 추가할 수 없습니다. 지정 이니셜라이저와 디이니셜라이저는 반드시 클래스 타입의 구현부에 위치해야 합니다(값 타입은 상관없습니다).



관련문서

The Swift Programming Language - Extensions





by yagom

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

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


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

RSS Feed 받기   


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

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

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

고차함수  (0) 2017.07.27
오류처리  (0) 2017.07.24
익스텐션  (0) 2017.07.20
프로토콜  (0) 2017.07.17
assert와 guard  (0) 2017.07.13
타입캐스팅  (2) 2017.07.10
Posted by yagom


오늘의 주제

1. 프로토콜
2. 익스텐션




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


지난 포스팅에서는 스위프트의 구조체와 클래스에 대해 알아봤습니다.


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

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

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

2017/02/28 - [Swift] - Swift - 구조체 클래스



이번에는 프로토콜과 익스텐션에 대해 알아보겠습니다 :)



프로토콜


프로토콜(Protocol)특정 역할을 수행하기 위한 메서드, 프로퍼티, 기타 요구사항 등의 청사진을 정의합니다. 구조체, 클래스, 열거형은 프로토콜을 채택(Adopted)해서 특정 기능을 수행하기 위한 프로토콜의 요구사항을 실제로 구현할 수 있습니다. 어떤 프로토콜의 요구사항을 모두 따르는 타입은 그 ‘프로토콜을 준수한다(Conform)’고 표현합니다. 타입에서 프로토콜의 요구사항을 충족시키려면 프로토콜이 제시하는 청사진의 기능을 모두 구현해야 합니다. 즉, 프로토콜은 기능을 정의하고 제시 할 뿐이지 스스로 기능을 구현하지는 않습니다. 


프로토콜 정의

프로토콜은 구조체, 클래스, 열거형의 모양과 비슷하게 정의할 수 있으며 protocol 키워드를 사용합니다. 


protocol 프로토콜 이름 {
    프로토콜 정의
}
구조체, 클래스, 열거형 등에서 프로토콜을 채택하려면 타입 이름 뒤에 콜론(:)을 붙여준 후 채택할 프로토콜 이름을 쉼표(,)로 구분하여 명시해줍니다. 

struct SomeStruct: AProtocol, AnotherProtocol {
    // 구조체 정의
}

class SomeClass: AProtocol, AnotherProtocol {
    // 클래스 정의
}

enum SomeEnum: AProtocol, AnotherProtocol {
    // 열거형 정의
}

위 코드의 각 타입은 AProtocol과 AnotherProtocol을 채택한 것입니다. 만약, 클래스가 다른 클래스를 상속받는다면 상속받을 클래스 이름 다음에 채택할 프로토콜을 나열해줍니다. 
class SomeClass: SuperClass, AProtocol, AnotherProtocol {
    // 클래스 정의
}

위의 SomeClass는 SuperClass를 상속받았으며 동시에 AProtocol과 AnotherProtocol 프로토콜을 채택한 클래스입니다. 

프로토콜 요구사항

프로토콜은 타입이 특정 기능을 수행하기 위해 필요한 기능을 요구합니다. 프로토콜이 자신을 채택한 타입에 요구하는 사항은 프로퍼티나 메서드와 같은 기능들입니다. 프로토콜은 프로퍼티, 메서드, 서브스크립트, 이니셜라이저 등의 기능을 요구할 수 있습니다.

프로퍼티 요구


프로토콜은 자신을 채택한 타입이 어떤 프로퍼티를 구현해야 하는지 요구할 수 있습니다. 그렇지만 프로토콜은 그 프로퍼티의 종류(연산 프로퍼티인지, 저장 프로퍼티인지 등)는 따로 신경쓰지 않습니다. 프로토콜을 채택한 타입은 프로토콜이 요구하는 프로퍼티의 이름과 타입만 맞도록 구현해주면 됩니다. 다만, 프로퍼티를 읽기 전용으로 할지 혹은 읽고 쓰기가 모두 가능하게 할지는 프로토콜이 정해야 합니다. 

프로토콜의 프로퍼티 요구사항은 항상 var 키워드를 사용한 변수 프로퍼티로 정의됩니다. 읽기와 쓰기가 모두 가능한 프로퍼티는 프로퍼티의 정의 뒤에 {get set}이라고 명시하며, 읽기 전용 프로퍼티는 프로퍼티의 정의 뒤에 {get}이라고 명시해줍니다. 

protocol SomeProtocol { var settableProperty: String { get set } var notNeedToBeSettableProperty: String { get } } protocol AnotherProtocol { static var someTypeProperty: Int { get set } static var anotherTypeProperty: Int { get } }


위 코드의 SomeProtocol에 정의된 settableProperty는 읽기와 쓰기 모두를 요구했고, notNeedToBeSettableProperty는 읽기만 가능하다면 어떻게 구현되어도 상관없다는 요구사항입니다. 타입 프로퍼티를 요구하려면 static 키워드를 사용합니다. 클래스의 타입 프로퍼티에는 상속 가능한 타입 프로퍼티인 class 타입 프로퍼티와 상속 불가능한 static 타입 프로퍼티가 있습니다만 이 두 타입 프로퍼티를 따로 구분하지 않고 모두 static 키워드 를 사용하여 타입 프로퍼티를 요구하면 됩니다. AnotherProtocol에 정의된 someProperty 와 anotherProperty는 모두 타입 프로퍼티를 요구합니다.

protocol Talkable {
    var topic: String { get set }
}

struct Person: Talkable {
    var topic: String
}

Talkable 프로토콜은 어떤 주제에 대해 말할 수 있게 하기 위한 프로퍼티인 topic를 요구합니다. 그래서 Talkable 프로토콜을 채택하여 준수하는 Person 클래스는 topic 프로퍼티를 가져야합니다.


메서드 요구


프로토콜은 특정 인스턴스 메서드나 타입 메서드를 요구할 수도 있습니다. 프로토콜이 요구할 메서드는 프로토콜 정의에서 작성합니다. 다만, 메서드의 실제 구현부인 중괄호({}) 부분은 제외하고 메서드의 이름, 매개변수, 반환 타입 등만 작성합니다. 프로토콜의 메서드 요구에서는 매개변수 기본값을 지정할 수 없습니다. 타입 메서드를 요구할 때는 타입 프로퍼티 요구와 마찬가지로 앞에 static 키워드를 명시합니다. static 키워드를 사용 하여 요구한 타입 메서드를 클래스에서 실제 구현할 때에는 static 키워드나 class 키워드 어느 쪽을 사용해도 무방합니다.

protocol Talkable {
    var topic: String { get set }
    func talk(to: Person)
}

struct Person: Talkable {
    var topic: String
    var name: String
    
    func talk(to: Person) {
        print("\(topic)에 대해 \(to.name)에게 이야기합니다")
    }
}

이니셜라이저 요구


프로토콜은 프로퍼티, 메서드 등과 마찬가지로 특정한 이니셜라이저를 요구할 수도 있습니다. 프로토콜에서 이니셜라이저를 요구하려면 메서드 요구와 마찬가지로 이니셜라이저를 정의하지만 구현은 하지 않습니다. 즉, 이니셜라이저의 매개변수를 지정하기만 할 뿐, 중괄호를 포함한 이니셜라이저 구현은 하지 않습니다. 


protocol Talkable {
    var topic: String { get set }
    func talk(to: Person)
    init(name: String, topic: String)
}

struct Person: Talkable {
    var topic: String
    var name: String
    
    func talk(to: Person) {
        print("\(topic)에 대해 \(to.name)에게 이야기합니다")
    }
    
    init(name: String, topic: String) {
        self.name = name
        self.topic = topic
    }
}

let yagom: Person = Person(name: "야곰", topic: "스위프트")
let hana: Person = Person(name: "하나", topic: "코딩")

yagom.talk(to: hana)
// 스위프트에 대해 하나에게 이야기합니다

프로토콜의 상속


프로토콜은 하나 이상의 프로토콜을 상속받아 기존 프로토콜의 요구사항보다 더 많은 요구사항을 추가할 수 있습니다. 프로토콜 상속 문법은 클래스의 상속 문법과 유사합니다. 

protocol Readable {
    func read()
}
protocol Writeable {
    func write()
}
protocol ReadSpeakable: Readable {
    func speak()
}
protocol ReadWriteSpeakable: Readable, Writeable {
    func speak()
}

class SomeClass: ReadWriteSpeakable {
    func read() {
        print("Read")
    }
    
    func write() {
        print("Write")
    }
    
    func speak() {
        print("Speak")
    }
}
위 코드의 ReadSpeakable 프로토콜은 Readable 프로토콜을 상속받았고 ReadWriteSpeakable 프로토콜은 Readable과 Writeable 프로토콜을 상속받았습니다. 그래서 ReadWriteSpeakable 프로토콜을 채택한 SomeClass는 세 프로토콜이 요구하는 read(), write(), speak() 메서드를 모두 구현해야 합니다. 


익스텐션

익스텐션(Extension)은 스위프트의 강력한 기능 중 하나입니다. 익스텐션은 구조체, 클래스, 열거형, 프로토콜 타입에 새로운 기능을 추가할 수 있는 기능입니다. 기능을 추가하려는 타입의 구현된 소스 코드를 알지 못하거나 볼 수 없다 해도, 타입만 알고 있다면 그 타입의 기능을 확장할 수도 있습니다.

스위프트의 익스텐션이 타입에 추가할 수 있는 기능은 다음과 같습니다. 

  • 연산 타입 프로퍼티 / 연산 인스턴스 프로퍼티 
  • 타입 메서드 / 인스턴스 메서드
  • 이니셜라이저
  • 서브스크립트 
  • 중첩 타입
  • 특정 프로토콜을 준수할 수 있도록 기능 추가 
익스텐션은 타입에 새로운 기능을 추가할 수는 있지만, 기존에 존재하는 기능을 재정의할 수는 없습니다. 클래스 의 상속과 익스텐션을 비교해보겠습니다. 이 둘은 비슷해보이지만 실제 성격은 많이 다릅니다. 

클래스의 상속은 클래스 타입에서만 가능하지만 익스텐션은 구조체, 클래스, 프로토콜 등에 적용이 가능합니다. 또 클래스의 상속은 특정 타입을 물려받아 하나의 새로운 타입을 정의하고 추가 기능을 구현하는 수직 확장이지만, 익스텐션은 기존의 타입에 기능을 추가하는 수평 확장입니다. 또, 상속을 받으면 기존 기능을 재정의할 수 있지만, 익스텐션은 재정의할 수 없다는 것도 큰 차이 중 하나입니다. 상황과 용도에 맞게 상속과 익스텐션을 선택하여 사용하면 됩니다. 

 

상속 

익스텐션 

확장 

수직 확장 

수평 확장 

사용 

클래스 타입에만 사용 

클래스, 구조체, 프로토콜, 제네릭 등 모든 타입 

 재정의

재정의 가능 

재정의 불가 


익스텐션을 사용하는 대신 원래 타입을 정의한 소스에 기능을 추가하는 방법도 있겠지만, 외부 라이브러리나 프레임워크를 가져다 썼다면 원본 소스를 수정하지 못합니다. 이처럼 외부에서 가져온 타입에 내가 원하는 기능을 추가하고자 할 때 익스텐션을 사용합니다. 따로 상속을 받지 않아도 되며, 구조체와 열거형에도 기능을 추가할 수 있으므로 익스텐션은 매우 편리한 기능입니다. 

익스텐션은 모든 타입에 적용할 수 있습니다. 모든 타입이라 함은 구조체, 열거형, 클래스, 프로토콜, 제네릭 타입 등을 뜻합니다. 즉, 익스텐션을 통해 모든 타입에 연산 프로퍼티, 메서드, 이니셜라이저, 서브스크립트, 중첩 데이터 타입 등을 추가할 수 있습니다.

더불어 익스텐션은 프로토콜과 함께 사용하면 굉장히 강력한 기능을 선사합니다. 그 내용은 다음 포스팅인 프로토콜 지향 프로그래밍에서 조금 더 자세히 다루겠습니다. 


익스텐션 문법


익스텐션은 extension이라는 키워드를 사용하여 선언합니다. 
extension 확장할 타입 이름 {
    // 타입에 추가될 새로운 기능 구현
}
익스텐션은 기존에 존재하는 타입이 추가적으로 다른 프로토콜을 채택할 수 있도록 확장할 수도 있습니다. 이런 경우에는 클래스나 구조체에서 사용하던 것과 똑같은 방법으로 프로토콜 이름을 나열해줍니다. 
extension 확장할 타입 이름: 프로토콜1, 프로토콜2, 프로토콜3 {
    // 프로토콜 요구사항 구현
}

스위프트 라이브러리를 살펴보면 실제로 익스텐션이 굉장히 많이 사용되고 있음을 알 수 있습니다. Double 타입에는 수많은 프로퍼티와 메서드, 이니셜라이저가 정의되어 있으며 수많은 프로토콜을 채택하고 있을 것이라고 예상되지만, 실제로 Double 타입의 정의를 살펴보면 그 모든것이 다 정의되어 있지는 않습니다. 

그러면 Double 타입이 채택하고 준수해야 하는 수많은 프로토콜은 어디로 갔을까요? 어디에서 채택하고 어디에서 준수하도록 정의되어 있을까요? 당연히 답은 익스텐션입니다. 이처럼 스위프트 표준 라이브러리 타입의 기능은 대부분 익스텐션으로 구현되어 있습니다. Double 외에도 다른 타입들의 정의와 익스텐션을 찾아보면 더 많은 예를 보실 수 있습니다. 꼭 한 번 찾아보세요! 

익스텐션으로 확장할 수 있는 항목 

익스텐션을 통해 추가할 수 있는 기능에는 연산 프로퍼티, 메서드, 이니셜라이저, 서브스크립트, 중첩 데이터 타입 등이 있습니다.

연산 프로퍼티 추가


extension Int {
    var isEven: Bool {
        return self % 2 == 0
    }
    var isOdd: Bool {
        return self % 2 == 1
    }
}

print(1.isEven) // false
print(2.isEven) // true
print(1.isOdd)  // true
print(2.isOdd)  // false

var number: Int = 3
print(number.isEven) // false
print(number.isOdd) // true

number = 2
print(number.isEven) // true
print(number.isOdd) // false

위 코드의 익스텐션은 Int 타입에 두 개의 연산 프로퍼티를 추가한 것입니다. Int 타입의 인스턴스가 홀수인지 짝수인지 판별하여 Bool 타입으로 알려주는 연산 프로퍼티입니다. 익스텐션으로 Int 타입에 추가해준 연산 프로퍼티는 Int 타입의 어떤 인스턴스에도 사용이 가능합니다. 위의 코드처럼 인스턴스 연산 프로퍼티를 추가할 수도 있으며, static 키워드를 사용하여 타입 연산 프로퍼티도 추가할 수 있습니다. 


메서드 추가


익스텐션을 통해 타입에 메서드를 추가할 수 있습니다.

extension Int {
    func multiply(by n: Int) -> Int {
        return self * n
    }
}
print(3.multiply(by: 2))  // 6
print(4.multiply(by: 5))  // 20

var number: Int = 3
print(number.multiply(by: 2))   // 6
print(number.multiply(by: 3))   // 9
위 코드의 익스텐션을 통해 Int 타입에 인스턴스 메서드인 multiply(by:) 메서드를 추가했습니다. 여러 기능을 여러 익스텐션 블록으로 나눠서 구현해도 전혀 문제가 없습니다. 관련된 기능별로 하나의 익스텐션 블록에 묶어주는 것도 좋습니다. 


이니셜라이저 추가


인스턴스를 초기화(이니셜라이즈)할 때 인스턴스 초기화에 필요한 다양한 데이터를 전달받을 수 있도록 여러 종류의 이니셜라이저를 만들 수 있습니다. 타입의 정의부에 이니셜라이저를 추가하지 않더라도 익스텐션을 통해 이니셜라이저를 추가할 수 있습니다. 

하지만 익스텐션으로 클래스 타입에 편의 이니셜라이저는 추가할 수 있지만, 지정 이니셜라이저는 추가할 수 없습니다. 지정 이니셜라이저와 디이니셜라이저는 반드시 클래스 타입의 구현부에 위치해야 합니다.(값 타입은 상관없습니다.) 

extension String { subscript(appendValue: String) -> String { return self + appendValue } subscript(repeatCount: UInt) -> String { var str: String = "" for _ in 0..<repeatCount { str += self } return str } } print("abc"["def"]) // "abcdef" print("abc"[3]) // "abcabcabc"


이번엔 스위프트의 프로토콜과 익스텐션 대해 알아봤습니다. 다음 포스팅에서는 프로토콜 지향 프로그래밍(Protocol Oriented Programming, POP) 대해 알아보겠습니다. 

다음 번에 또 뵈어요~ 고맙습니다 :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 받기   


저작자 표시 비영리 변경 금지
신고
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


티스토리 툴바