WatchKit 확장자와 함께 쓰일 iOS 앱 간의 통신을 시작시키는 객체
iOS 앱과 watchOS 앱은 실행 중에 이 클래스의 인스턴스를 생성하고 구성해야 합니다. 두 세션 객체가 모두 활성화된 경우, 두 프로세스는 즉시 메시지를 주고 받을 수 있습니다. 하나의 세션만 활성화된 경우에도 활성 세션은 업데이트를 보내고 파일을 전송할 수 있지만, 이러한 전송은 기회주의적으로 백그라운드에서 발생합니다.
중요
메시지를 보내거나 연결 상태에 대한 정보를 얻기 전에 세션 객체를 구성하고 활성화해야 합니다. 세션을 활성화하기 전에 현재 장치가 Watch Connectivity 프레임워크를 사용할 수 있는지 확인하려면 isSupported() 메서드를 호출할 수 있습니다.
세션 구성과 실행
세션을 구성하고 활성화하려면 기본 세션 객체에 delegate를 할당하고 해당 객체의 activate() 메서드를 호출하면 됩니다. 이를 Listing 1에 표시된대로 수행합니다. WatchKit 확장 프로그램과 iOS 앱은 각각 자체 세션 객체를 구성해야 합니다. 세션을 활성화하면 두 앱 간에 연결이 설정됩니다.
Listing 1. 세션 구성하고 활성화시키기
if WCSession.isSupported() {
let session = WCSession.defaultSession()
session.delegate = self
session.activateSession()
}
여러개의 애플워치를 같은 아이폰에 페어링을 지원하기 위해서는 양쪽 앱에서 session delegate은 활성화 API를 구현해야 합니다. session(_:activationDidCompleteWith:error:) 메서드를 구현하여 세션이 앱이 비동기 작동을 지원하는지 알려야 합니다.
여러 시계를 동일한 iPhone에 페어링하는 것을 지원하려면, 두 앱의 세션 대리인은 활성화 API를 구현해야 합니다. 다른 Apple Watch 간의 전환을 관리하려면 iOS 앱의 session delegate에서 sessionDidBecomeInactive(_:) 및 sessionDidDeactivate(_:) 메소드를 구현해야 합니다.
중요
delegate가 비동기 활성화 및 활성화 상태 변경에 대한 적절한 메서드를 구현하지 않으면 앱이 완전히 Apple Watch 지원에서 제외됩니다. 제외되면 사용자가 한 Apple Watch에서 다른 Apple Watch로 전환할 때 앱에 중요한 영향을 미칩니다. 전환이 발생하면 앱의 세션이 비활성화됩니다. 그 후에 앱이 백그라운드로 전환되면 시스템이 앱을 종료합니다. (백그라운드 실행 모드는 앱이 종료되는 것을 방지하지 않습니다.) 다음에 앱이 다시 시작되면 새 Apple Watch와 연결됩니다.
앱은 세션이 활성 상태인 경우에만 전송을 시작할 수 있습니다. 즉, activationState가 WCSessionActivationState.activated로 설정될 때입니다. iOS 앱은 백그라운드 메시지를 전송하기 전에 isPaired 및 isWatchAppInstalled 속성을 확인해야 하며, 필요에 따라 다른 속성도 확인해야 할 수 있습니다. 확인해야 할 대부분의 속성은 세션이 활성 상태일 때만 유효합니다. 다른 시간에는 속성의 값이 정의되지 않을 수 있습니다. activationState 속성은 항상 유효하며, 세션의 현재 활성 상태를 포함합니다.
delegate 객체의 메서드를 구현하기 위해서는 링크를 확인하세요
여러 Apple Watch와의 통신 지원
iOS 9.3 이상을 실행하는 iPhone은 watchOS 2.2 이상을 실행하는 여러 Apple Watch와 페어링할 수 있습니다. Watch 앱에서는 세션의 비동기 활성화를 지원해야 하지만 이는 필수가 아닙니다. iOS 앱에서는 세션의 비동기 활성화를 지원하고 세션 객체의 활성화 및 비활성화를 모니터링해야 합니다. 이를 위해 session delegate 에서 다음 메서드를 구현해야 합니다:
* session(_:activationDidCompleteWith:error:)
* sessionDidBecomeInactive(_:)
* sessionDidDeactivate(_:)
그림 1은 사용자가 한 Apple Watch에서 다른 Apple Watch로 전환할 때 발생하는 이벤트 시퀀스를 보여줍니다. 자동 전환이 활성화되면 한 번에 한 Apple Watch만 iOS 앱과 통신합니다. 각 Apple Watch의 Watch 앱은 활성 상태로 유지되지만 전환 중에 iOS 앱은 비활성 및 비활성 상태로 이동합니다. 비활성 상태로 이동하면 세션이 이미 수신된 데이터를 전달할 수 있는 시간이 조금 생깁니다. 그 데이터가 전달되면 세션은 비활성화 상태로 이동합니다. 그때 iOS 앱은 새로 활성화된 Apple Watch에 다시 연결하기 위해 activate() 메서드를 호출해야 합니다. 이 예에서는 이제 두 번째 Apple Watch입니다.
iOS 앱은 watchDirectoryURL 속성을 사용하여 특정 Apple Watch에서 실행 중인 Watch 앱의 단일 인스턴스에만 해당하는 데이터를 저장할 수 있습니다. 대부분의 경우, 각각의 Watch 앱 인스턴스에서 표시하는 데이터는 동일합니다. 그러나 iOS 앱이 Watch 앱과 올바르게 상호 작용하도록 필요한 구성 데이터, 환경 설정 또는 기타 데이터 파일을 저장하는 경우가 있습니다. 그렇다면 iOS 앱을 업데이트하기 위해 활성화 및 비활성화 프로세스를 사용하십시오.
반대편 앱과 통신하기
상대 앱과의 데이터 전송은 activationState 속성이 WCSessionActivationState.activated로 설정된 경우에만 시작할 수 있습니다. iOS 앱은 데이터 전송을 시작하기 전에 Watch 앱이 설치되었는지 확인해야 합니다. 다음 중 하나의 방법으로 전송을 시작할 수 있습니다:
1. WCSession.updateApplicationContext(_:) 메서드를 사용하여 최근 상태 정보를 상대 앱에 전달합니다. 상대방이 깨어날 때, 이 정보를 사용하여 자체 상태를 업데이트할 수 있습니다. 예를 들어, 백그라운드 앱 새로 고침을 지원하는 iOS 앱은 백그라운드 실행 시간의 일부를 사용하여 해당하는 Watch 앱을 업데이트할 수 있습니다. 이 방법은 이전 데이터 사전을 덮어쓰므로 앱이 가장 최근 데이터 값을 필요로 할 때 이 방법을 사용하십시오.
- 심박수를 애플워치에서 아이폰으로 전송할 때 기준으로 지연시간 없이 바로 데이터 송수신 됩니다.
2. WCSession.sendMessage(_:replyHandler:errorHandler:) 또는 sendMessageData(_:replyHandler:errorHandler:) 메서드를 사용하여 접근 가능한 상대 앱에 데이터를 전송합니다. 이 메서드는 iOS 앱과 WatchKit 확장 사이의 즉각적인 통신을 위해 의도되었습니다. 이 메서드가 성공하려면 현재 isReachable 속성이 true여야 합니다.
- 심박수를 애플워치에서 아이폰으로 전송할 때 기준으로 5초 걸립니다.
3. WCSession.transferUserInfo(_:) 메서드를 사용하여 백그라운드에서 데이터 사전을 전송합니다. 전송된 데이터 사전은 상대방에게 전달되기 위해 대기열에 넣으며, 현재 앱이 일시 중단되거나 종료되면 전송이 계속됩니다.
4. WCSession.transferFile(_:metadata:) 메서드를 사용하여 백그라운드에서 파일을 전송합니다. 이 메서드는 사전 값 이상을 보내고 싶을 때 사용합니다. 예를 들어, 이미지나 파일 기반 문서를 보내려면 이 방법을 사용하십시오.
5. iOS에서 WCSession.transferCurrentComplicationUserInfo(_:) 메서드를 사용하여 Watch 앱의 복잡한 데이터를 전송합니다. 이 메서드의 사용은 복잡한 시간 예산에 영향을 미칩니다.
메시지를 상대 앱에 보낼 때, 백그라운드 메시지는 대기열에 넣어 순서대로 전송됩니다. 들어오는 메시지도 마찬가지로 대기열에 넣어 수신된 순서대로 delegate에 전달됩니다. sendMessage(_:replyHandler:errorHandler:), sendMessageData(_:replyHandler:errorHandler:), 및 transferCurrentComplicationUserInfo(_:) 메서드를 사용하여 전송된 데이터는 더 높은 우선 순위를 가지며 즉시 전송됩니다. 앱에서 수신한 모든 메시지는 백그라운드 스레드에서 순차적으로 session delegate 에 전달됩니다.
참고
백그라운드 전송은 즉시 전달되지 않습니다. 시스템은 데이터를 가능한 빨리 전송하지만 전송이 즉시 발생하지는 않으며 전송을 약간 지연하여 전력 사용을 개선할 수 있습니다. 또한, 대량의 데이터 파일을 보내는 것은 데이터를 다른 기기로 전송하고 수신 측에서 처리하는 데 상당한 시간이 필요합니다. 메시지를 보낼 때는 앱이 필요로 하는 데이터만 보내십시오.
모든 전송은 전력을 소비하는 상대 앱에 데이터를 전송합니다. 매번 모든 데이터를 보내는 대신 변경된 항목만 보내십시오. 오류를 처리하고 데이터 전송이 실패할 경우 대체 방법을 제공할 수 있도록 준비하십시오. 데이터가 대상 장치에 충분한 공간이 없거나 데이터 자체가 형식이 잘못되었거나 통신 오류가 발생한 경우 오류가 발생할 수 있습니다. 핸들러 코드에서 오류를 확인하고 적절한 조치를 취하십시오.
기본 세션 가져오기
class func isSupported() -> Bool
: 현재 iOS 기기가 session 객체를 사용할 수 있는지에 대한 여부를 Bool 값으로 반환
class var 'default': WCSession
: 현재 기기를 위한 싱글톤 session 객체를 반환합니다
세션 구성하기
var delegate: (any WCSessionDelegate)?
: session 객체를 위한 delegate
func activate( )
: session을 비동기적으로 활성화 시키기
var activationState: WCSessionActivationState
: 현재 session의 활성화 상태
페어링된 기기의 정보 가져오기
var ispaired: Bool
: 현재 iPhone이 Apple Watch와 연결이 됐는지를 나타내는 Bool 값
var iOSDeviceNeedsUnlockAfterRebootForReachability: Bool
: 페어링된 iPhone이 접근할 수 있도록 잠금 해제된 상태에 있어야 하는지 여부를 나타내는 Bool 값
var isWatchAppInstalled: Bool
: 현재 페어링됐고 활성화된 Apple Watch가 앱을 설치했는지 여부를 나타내는 Bool 값
var isCompanionAppInstalled: Bool
: 동반자가 앱을 설치했는지 여부를 나타내는 Bool 값
var isComplicationEnabled: Bool
: Apple Watch 앱의 컴플리케이션이 현재 페어링되고 활성화된 Apple Watch에서 사용 중인지 여부를 나타내는 Bool 값
var watchDirectoryURL: URL?
: 현재 페어링됐고 활성화된 Apple Watch에 데이터를 저장할 위치
세션의 도달 가능성
var isReachable: Bool
: 반대편 앱이 실시간 메세지가 가능한지를 나타내는 Bool 값
백그라운드 업데이트 관리하기
func updateApplicationContext([String : Any]) throws
: 딕셔너리로 된 값을 활성화, 페어링된 기기에 전송
var applicationContext: [String : Any]
: 가장 최근의 텍스트 형태의 데이터를 활성화, 페어링된 기기에 전송
var receivedApplicationContext: [String : Any]
: 활성화, 페어링된 기기로부터 가장 마지막에 받은 딕셔너리 데이터 값
메시지 전송하기
func sendMessage([String : Any], replyHandler: (([String : Any]) -> Void)?, errorHandler: ((any Error) -> Void)?)
: 즉시 활성화, 페어링된 기기에 메시지를 전송하고 선택적으로 response를 handle합니다.
func sendMessageData(Data, replyHandler: ((Data) -> Void)?, errorHandler: ((any Error) -> Void)?)
: 활성화, 페어링된 기기에 데이터 객체를 즉시 전송하고 선택적으로 response를 handle합니다.
완료된 데이터 업데이트하기
var remainingComplicationUserInfoTransfers: Int
: iOS 앱에서 WatchKit 확장 프로그램으로 복잡한 데이터를 보낼 수 있는 남은 횟수.
func transferCurrentComplicationUserInfo([String : Any]) -> WCSessionUserInfoTransfer
: iOS 앱에서 WatchKit 확장 프로그램으로 복잡한 관련 데이터를 보냅니다.
백그라운드에서 데이터 전송하기
func transferUserInfo([String : Any]) -> WCSessionUserInfoTransfer
: 상대편에 특정 딕셔너리 데이터 전송합니다.
var outstandingUserInfoTransfers: [WCSessionUserInfoTransfer]
: 진행 중인 데이터 전송의 배열.
백그라운드에서 파일 전송하기
func transferFile(URL, metadata: [String : Any]?) -> WCSessionFileTransfer
: 상대편에 특정 파일과 선택적으로 딕셔너리 값을 전송합니다.
var outstandingFileTransfers: [WCSessionFileTransfer]
: 진행 중인 파일 전송의 배열.
var hasContentPending: Bool
: 세션에 전달할 콘텐츠가 더 있는지 여부를 나타내는 부울 값.
WCSessionDelegate
WCSession 객체로부터 받은 메시지를 인식하여 콜백함수들을 실행할 대리자입니다
세션 객체는 페어링되고 활성화된 iPhone의 WatchKit 확장 프로그램과 동반 iOS 앱 간의 통신에 사용됩니다. 세션 객체를 구성할 때 해당 프로토콜을 구현하는 delegate 객체를 지정해야 합니다. 세션은 delegate 메서드를 호출하여 상대 앱으로부터의 수신 데이터를 전달하고 세션 관련 변경 사항을 관리합니다. 이 프로토콜의 대부분 메서드는 선택 사항입니다. 앱에서는 앱이 지원하는 데이터 전송 작업에 응답하기 위해 필요한 메서드만 구현합니다. 그러나 앱은 비동기 활성화를 지원하는 session(_:activationDidCompleteWith:error:) 메서드를 반드시 구현해야 합니다. iOS에서는 다중 Apple Watch를 지원하기 위해 sessionDidBecomeInactive(_:), sessionDidDeactivate(_:) 메서드도 구현해야 합니다.
WCSession 객체는 delegate 메서드를 직렬로 호출하므로 메서드 구현이 재진입 가능할 필요가 없습니다. 즉시 메시지는 WatchKit 확장 프로그램과 iOS 앱이 모두 실행 중일 때에만 전송될 수 있습니다. 그러나 컨텍스트 업데이트와 파일 전송은 언제든지 시작되고 백그라운드에서 다른 기기로 전달될 수 있습니다. 모든 전송은 보낸 순서대로 전달됩니다.
여러 대의 Apple Watch와의 통신 지원
iOS 9.3 이상을 실행하는 iPhone은 watchOS 2.2 이상을 실행하는 여러 대의 Apple Watch와 페어링할 수 있습니다. 세션 대리자에 다음 메서드를 구현하세요:
* session(_:activationDidCompleteWith:error:)
* sessionDidBecomeInactive(_:)(iOS 전용)
* sessionDidDeactivate(_:)(iOS 전용)
iOS 앱에서 세션의 활성화 상태를 추적하기 위해 활성화 관련 메서드를 사용하세요. 사용자의 iPhone에서 Auto Switch가 활성화된 경우, 사용자가 현재 활성화된 Apple Watch와 다른 Apple Watch를 착용하면 세션이 자동으로 비활성 상태로 전환됩니다. (Auto Switch가 비활성화된 경우, 사용자는 수동으로 활성화된 Apple Watch를 선택해야 합니다.) iOS 앱이 비활성 상태일 때 시스템은 앱을 비활성화된 상태로 이동하기 전에 수신된 모든 데이터를 전달합니다. 비활성 상태나 비활성화된 상태에서는 새로운 전송을 시작할 수 없습니다. iOS 앱이 비활성화된 상태에 도달하면 세션의 activate() 메서드를 다시 호출하여 새로운 Apple Watch에 연결하십시오.
세션 활성 관리하기
func session(WCSession, activationDidCompleteWith: WCSessionActivationState, error: (any Error)?)
: delegate에게 세션이 시작을 완료했다고 알려줍니다.
func sessionDidBecomeInactive(WCSession)
: delegate에게 현재 Apple Watch와 통신을 그만하라고 알려줍니다.
func sessionDidDeactivate(WCSession)
: delegate에게 세션이 이전 세션의 모든 데이터를 전달했으며, Apple Watch와의 통신이 끝났다고 알려줍니다.
상태 변화 관리하기
func sessionWatchStateDidChange(WCSession)
: 상대방의 정보에 대한 변경을 나타냅니다
func sessionReachabilityDidChange(WCSession)
: 상대방의 도달 가능성 상태에 대한 변화를 나타냅니다.
func sessionCompanionAppInstalledDidChange(WCSession)
: 상대방 앱의 설치 상태에 대한 변경을 나타냅니다.
Context 데이터 수신하기
func session(WCSession, didReceiveApplicationContext: [String : Any])
: delegate에게 세션이 상대방으로부터 context 데이터를 받았다고 알려줍니다.
즉각적인 메시지 받기
func session(WCSession, didReceiveMessage: [String : Any])
: delegate에게 즉각적인 메시지가 도착했다고 말합니다
func session(WCSession, didReceiveMessage: [String : Any], replyHandler: ([String : Any]) -> Void)
: delegate에게 즉각적인 메시지가 도착했다고 말하고 handler를 제공합니다.
func session(WCSession, didReceiveMessageData: Data, replyHandler: (Data) -> Void)
: delegate에게 즉각적인 data 메시지가 도착했다고 말합니다.
func session(WCSession, didReceiveMessageData: Data, replyHandler: (Handler: (Data) -> Void)
: delegate에게 즉각적인 data 메시지가 도착했다고 말하고 handler를 제공합니다.
딕셔너리 데이터 전송 관리하기
func session(WCSession, didReceiveUserInfo: [String : Any])
: delegate에게 세션이 상대방으로부터 데이터 디렉토리를 성공적으로 받았다고 말한다.
func session(WCSession, didFinish: WCSessionUserInfoTransfer, error: (any Error)?)
: delegate에게 데이터 전송 작업이 성공적으로 완료되었거나 오류로 인해 종료되었다고 알려줍니다.
파일 전송 관리하기
func session(WCSession, didReceive: WCSessionFile)
: delegate에게 세션이 상대방으로부터 파일을 성공적으로 받았다고 알려줍니다.
func session(WCSession, didFinish: WCSessionFileTransfer, error: (any Error)?)
: delegate에게 오류로 인해 파일 전송이 성공적으로 완료되었거나 종료되었음을 알려줍니다.
'SwiftUI' 카테고리의 다른 글
Referencing instance method 'setValue(forKey:to:)' on 'Optional' requires that conform to 'PersistentModel' (0) | 2024.03.18 |
---|---|
SwiftData 로 영구저장하기 (0) | 2024.03.18 |
애플워치로 실시간 심박수 가져오기, 애플워치 타깃 추가하기 (0) | 2024.03.14 |
사용자의 운동 경로 기록 가져오기 (0) | 2024.03.13 |
사용자의 운동 경로 기록하기 (0) | 2024.03.13 |