어떤 글에서 개발환경에서는 handoff 기능을 테스트할 수 없다고 해서 궁금해졌다..
handoff 는 무엇이며.. 시뮬레이터에서는 왜 테스트해보지 못하는 걸까?
아직 명확하게 알진 못했지만 계속 테스트를 하다 보니 짐작이 가는 이유는 있었는데 그게 맞는지는 확실하지 않다.. 누군가 잘 아는 사람 있으면 같이 이야기해보고 싶네 ㅎㅎ
일단 handoff라는 용어는 처음 들어봤는데 알고 보니 친숙한 기능이었다.
우리가 아이폰 크롬에서 뭘 검색하고 있는데 맥북 dock에서 이런 표시가 뜨는 것을 본 적이 있을 것이다.
이런 기능이 바로 handoff이다. 아이폰에서도 이 앱을 사용하고 있다는 것을 디바이스를 초월하여 알려주고 있다. 앱 아이콘을 누르면 내가 크롬에서 검색하고 작업하고 있었던 것을 그대로 가져와서 보여준다.
즉, 핸드오프 기능을 채택하고 있는 앱들은 다른 디바이스여도 중단된 작업을 그대로 가져와서 쓸 수 있는 편리함을 제공하는 것이다. 물론 같은 애플 아이디로 로그인되어 있어야 하고 핸드오프 기능이 켜져있어야 하는 등 최소한의 조건을 만족해야 한다.
이렇게 대충 handoff에 대한 감을 잡았다면 좀 더 자세하게 들여다보자.
# 🍀 TaskManagement, NSUserActivity는 또 뭘까?
handoff를 설명하기 전에 TaskManagement와 NSUserActivity에 대한 설명과 관계성에 대해서 알아볼 필요가 있다.
TaskManagement는 말 그대로 task 관리.
앱의 작업(work)과 사용자 및 시스템과의 상호작용을 관리하는 것을 말한다.
이렇게 task를 관리하는 것 중에 Activity Sharing이라는 카테고리 안에 바로 NSUserActivity라는 클래스가 있는데 Activity Sharing이라는 것만 들어도 NSUserActivity의 개념이 대충 서죠??
맞아요. 처음에 말했던 것과 같이 여러 개의 디바이스에서 작업을 이어서 할 수 있게 사용자의 어떤 행동을 공유하는 handoff와 같은 기능들을 가능하게 만들어주는 객체를 만들 수 있는 게 바로 NSUserActivity이다.
그럼 NSUserActivity라는 클래스를 좀 더 알아볼까?
A representation of the state of your app at a moment in time. 공식문서의 정의는 이렇다.
특정 시점의 앱 상태를 표현하는 클래스...흠..풀어서 설명하자면
특정 시점의 앱 상태를 캡처하고 나중에 사용할 수 있는 방법을 제공한다. 즉, vewing app content, editing a document, viewing a web page, or watching a video 등 사용자가 수행한 작업에 대한 정보를 캡처하려면 이 NSUserActivity 객체를 만들면 되는 것이다. 앱은 해당 객체의 정보를 사용하면 적절한 상태로 복원할 수 있다.
단, key moment(중요한 순간)에 NSUserActivity 객체를 만들고 이를 시스템에 등록한다. 예를 들어, 웹페이지를 열거나, 앱이 백그라운드로 이동하거나, 사용자가 앱에서 다른 중요한 작업을 수행할 때 NSUserActivity 객체를 만들 수 있는 것이다.
중요한 순간이라고 한정지은 이유는!! 앱의 모든 작업을 추적할 수 있는 방법이 아니므로, 사소한 변경작업에는 사용하지 말아야 하고 다른 디바이스에서 계속 진행할 수 있는 중요한 체크 포인트에서만 사용되기 때문이다.
그럼 간단하게 TaskManagement와 NSUserActivity의 개념에 대해 알아봤으니 handoff에 대해 자세히 알아보자
# 🍀 handoff, search, publicIndexing
왜 handoff를 얘기하다가 갑자기 search와 publicIndexing이라는 것까지 나오나요..물으신다면 ㅎㅎ
일단 우리는 위에서 NSUserActivity의 객체를 생성함으로써 "특정시점"에 "앱의 상태를 캡처"하고 "나중에 사용"할 수 있다고 했다. 그럼 여기서 질문!!
캡처한 앱의 상태를 어떻게 사용할 건데??
이에 대한 답은 세 가지로 분류할 수 있고 그중에 하나가 handoff이다!!
user activity에 대한 객체를 생성하고 그에 대한 프로퍼티 세 개 중 하나 이상을 활성화해서 유저의 활동에 대해 어떤 작업을 할 것인지 구성하면 된다.
- isEligibleForHandoff : Handoff를 사용하여 다른 장치에서 활동을 계속할 수 있는지 여부
- isEligibleForSearch : 활동을 기기 내 색인에 추가해야 하는지 여부
- isEligibleForPublicIndexing : 모든 iOS 사용자가 활동에 공개적으로 액세스 할 수 있는지 여부
이렇게 세 가지가 있지만 오늘은 handoff만 좀 더 자세하게 보겠다. search에 대해서는 아래에서 간단히 무엇인지 언급하겠다.
# 🍀 user activity 객체 만들어서 handoff 적용해 보기
앞서 isEligibleForHandoff에서 정의되었던 것처럼사용자가 앱에서 어떠한 활동을 했다가 중단했을 때 다른 디바이스(아이폰 아이패드 맥북 등)에서 중단한 작업을 이어 할 수 있도록 하는 것이다. 메일, 캘린더, 연락처, 사파리 등 다양한 Apple 앱에서 handoff가 지원되고 있고, 잘 구현만 한다면 우리가 만드는 앱에서도 handoff 가능하다!
자 그럼 일단 어떻게 코드로 구현하는지 살펴보자.
생각보다 매우 간단하다.
첫째, Info.plist 에서 NSUserActivityType 추가
NSUserActivityType 추가하고 value에 타입을 식별할 수 있는 String을 value에 넣어준다
둘째, ViewController에서 user activity 객체를 만들어준다.
객체를 만들어주고 타이틀, 활성화할 작업 등을 구현해 주면 된다.
생성한 객체를 시스템? 에 등록해서 task가 management 되도록 하려면 becomeCurrent() 메소드를 호출해야 한다고 하니 잊지 말자.
private let myUserActivity: NSUserActivity = NSUserActivity(activityType: "heid.handoff")
override func viewDidLoad() {
super.viewDidLoad()
setupUserActivity()
}
func setupUserActivity() {
self.myUserActivity.title = "Heidi"
self.myUserActivity.isEligibleForSearch = true
self.myUserActivity.isEligibleForHandoff = true
self.myUserActivity.webpageURL = URL(string: "https://heidi-dev.tistory.com/")
self.userActivity = self.myUserActivity
self.userActivity?.becomeCurrent()
}
# 🍀 handoff에서 확인해야 할 부분
아마 위처럼 구현한다고 해도 아래 나열한 부분들이 만족되어야 작동할 것이다.
- 각 기기에서 동일한 애플 아이디로 로그인해야 한다
- 기기가 서로의 Bluetooth 범위(약 10미터) 내에 있어야 한다.
- 각 기기 전용 소프트웨어 버전이 최소 iOS 10, iPadOS 13, macOS 10.10, watchOS 1.0 이상으로 설치되어 있어야 한다..
- 맥, 아이폰, 아이패드 즉, 작업을 이어하고 싶은 디바이스는 각각 와이파이, 블루투스, handoff가 켜져 있어야 한다
* mac과 iphone에서 handoff 켜져 있는지 확인하는 법
# 🍀 handoff 된 건지 어디서 볼 수 있나요..
* 다른 기기에서 iPhone으로 handoff
아이폰에서 handoff가 어디에 표시되는 건지 했는데 무심코 지나쳤던 앱 전환기아래에 뜨더라구요??
아하 이게 handoff 기능 때문에 떴던 거군.. 알아두기!
* iPhone에서 다른기기로 handoff
이 경우는 처음에 언급했던 것처럼 mac이나 ipad라면 Dock에 뜹니다.
# 🍀 그래서.. 시뮬레이터에서 테스트가 가능해?
내가 아이폰, 아이패드, 맥북 시뮬레이터 등에 깔아서 테스트를 해봤지만.
답은 "불가능하다"이다.
Handoff가 개발 시점 환경인 시뮬레이터에서 테스트가 안된다는 글에 Message UI도 테스트가 안된다고 나와있는데 Handoff를 공부하고 테스트하면서 대충 왜 안 되는 건지 감이 잡혔다.
생각해 보면 두 기능 다 2개 이상의 기기에서 상호작용이 있어야 하는 건데 개발 환경에서는 개발 과정을 실행시켜 볼 순 있어도 상호작용을 할 수는 없기 때문 아닐까??...라고 사료된다...((확신하지 못한다는 뜻))
그럼 이런 기능들은 개발환경에서 어떻게 테스트해 보지?? 배포하는 방법밖에는 없는 걸까?
확실하게 답을 아는 분 계시다면 댓글 부탁드려요 ㅎㅎ
# 🍀 뽀너스!! 개발 환경에서 테스트 가능한 isEligibleForSearch
user activity에 대한 객체에서 아래 프로퍼티 중 한 개 이상을 활성화해야 한다고 언급했다.
- isEligibleForHandoff : Handoff를 사용하여 다른 장치에서 활동을 계속할 수 있는지 여부
- isEligibleForSearch : 활동을 기기 내 색인에 추가해야 하는지 여부
- isEligibleForPublicIndexing : 모든 iOS 사용자가 활동에 공개적으로 액세스 할 수 있는지 여부
일단 isEligibleForHandoff는 개발환경에서 테스트 안 되는 걸 확인했으니 isEligibleForSearch는 테스트 가능한지 알아보자.
isEligibleForSearch는 뭔데?
NSUserActivity 개체에 사람이 나중에 검색할 수 있는 정보가 포함되어 있으면 아이폰 내 검색 시스템인 spotlight에서 검색할 때 사용자 활동 개체에서 얻은 결과가 포함될 수 있도록 하는 것.
예를 들어 이렇게 객체에서 isEligibleForSearch를 활성화했으면
func setupUserActivity() {
self.myUserActivity.title = "Heidi"
self.myUserActivity.isEligibleForSearch = true
self.myUserActivity.isEligibleForHandoff = true
self.myUserActivity.webpageURL = URL(string: "https://heidi-dev.tistory.com/")
self.userActivity = self.myUserActivity
self.userActivity?.becomeCurrent()
}
이렇게 검색 시스템에서 검색 결과에 해당 앱이 포함될 수 있도록 하는 것이다.
참고
https://developer.apple.com/documentation/foundation/task_management
https://developer.apple.com/documentation/foundation/nsuseractivity
https://zeddios.tistory.com/667
https://support.apple.com/ko-kr/guide/iphone/iphcec5d0a9d/ios
'iOS' 카테고리의 다른 글
[iOS] 앱의 시작지점 @main (1) | 2024.02.11 |
---|---|
[iOS] Core Data (3) | codegen(generating code) 이해해보자! (0) | 2023.12.17 |
[iOS] Core Data (2) | CRUD (1) | 2023.12.10 |
[iOS] Core Data (1) | Persistence (1) | 2023.12.09 |
[Swift] Bounds와 Frame에 대해 알아보자 (2) | 2023.11.18 |