Meet the Contact Access Button (feat. WWDC 2024)
안녕하세요. 그린입니다 🍏
이번 포스팅에서는 연락처에 접근하는 버튼에 대해 WWDC 2024 영상을 보며 알아보려고 합니다 🙋🏻
앱에서 새로운 연락처 권한을 부여하는 모드와 앱에서 연락처에 접근 하는 방법에 대해 개선된 포인트들을 살펴볼 수 있어요 😃
또한, 연락처 액세스 버튼을 앱에 통합해 필요에 따라서 추가 연락처를 공유하고 연락처 권한 부여에 대해 더 쉽게 제공하는 방법에 대해서 들어볼 수 있습니다.
마지막으로, 연락처 보안 기능과 버튼이 앱에 적합하지 않을 경우에 대체하여 사용할 수 있는 API도 다뤄봅니다!
그럼 바로 한번 알아볼까요? 🏃🏻
Meet the Contact Access Button
Limited access
iOS 18에서부터 제공되는 제한된 액세스 기능에 대해 알아봅니다.
iOS 18에선 연락처 인증에 연락처 DB의 일부만 공유하는 옵션이 존재합니다.
이것을 제한된 액세스라고 하죠.
연락처 인증 팝업은 이제 두단계로 제공이 됩니다.
첫번째로, 연락처를 앱과 공유할지 여부를 묻는 팝업이죠.
첫번째 팝업에서 연락처 공유를 허용한다면 두번째 시트가 나타납니다.
바로 제한된 연락처에 대해서만 선택해서 공유할지 아니면 전체 연락처를 공유할지 옵션입니다.
물론, 이 선택은 언제든 변경할 수 있어요.
제한된 연락처 허용을 선택하고 연락처들을 선택하면 선택한 연락처가 표시되어 확인을 최종적으로 요하는 화면이 나타납니다.
이런 인증 흐름 자체는 연락처 공유에 대해서 투명성과 제어 기능을 통해 개인 정보 보호를 크게 개선해줍니다.
즉, 이제 이 새로운 기능을 사용하면 4가지 인증 레벨이 있습니다.
여기서 Limited, 제한된 접근 레벨이 추가된것이죠.
전체 액세스와 동일하게 앱에서도 연락처 수정 및 생성도 가능합니다.
액세스가 제한되어 있을 경우 더 나은 경험을 제공하기 위해 iOS 18에선 앱에 추가 연락처에 대한 액세스 권한을 부여하는 두가지 새로운 API가 포함되었습니다.
먼저, 좌측은 보면 전체 연락처 액세스 선택 시트를 사용해서 앱을 종료하지 않고도 앱이 접근할 수 있는 연락처를 쉽게 변경할 수 있습니다.
다음으로, 연락처 액세스 버튼은 앱에서 바로 연락처에 대해 액세스를 관리할 수 있는 새롭게 나온 방법입니다.
즉, 왼쪽처럼 전체 화면에서 선택을 하는것이 아니라 해당 추가 버튼을 통해 탭 한번으로 새 연락처에 대해 액세스 권한을 부여할 수 있죠.
그럼 이렇게 연락처 접근에 대해 어떤것인지와 새로 나온 제한 접근에 대해 알아봤으니 바로 이전 살펴본 앱의 추가 연락처에 대해 액세스 권한을 주는 Contact Access Button에 대해 알아보겠습니다 😃
Contact Access Button
앱의 연락처 검색 플로우에 추가되면 버튼에 앱이 아직 액세스 할 수 없는 연락처에 대한 검색 결과가 표시됩니다.
이렇게 예시로 A가 들어간 이름을 검색할때 10명 넘게 존재하죠.
좀 더 특정하게 이름을 완성시키면 아직 부여되지 않은 연락처가 나옵니다.
여기서 Add 추가 버튼을 단순히 한번 탭하기만 하면 앱에 해당 연락처에 대한 액세스 권한이 부여되는것이죠.
전체 액세스 권한이 없어도 앱에서 모든 기능을 갖춘 연락처 선택 환경을 제공해줍니다.
훨씬 편해지지 않았나요?
물론, 기존에도 CNContactPickerViewController가 존재하여 필요하다면 전체 접근을 하지 않아도 선택한 연락처들만 가져오고 할 수 있었지만 ContactAccessButton으로 더 편리함을 챙기게 되었어요.
또한, 앱의 연락처 접근 인증 레벨이 결정되지 않았을때도 표시될 수 있습니다.
(다만 추가 버튼을 누르면 이제 인증에 대한 팝업 플로우가 나타나는거죠.)
즉, 앱에서 다른 스텝 거치지 않고 바로 추가하고 사용할 수 있으니까요 😃
다만 주의할점은 꼭 앱의 기능과 데이터가 해당 연락처 접근을 필요로 할 때 액세스를 요청해야 합니다.
아마 그렇지 않으면 앱 심사를 통과하지 못할 가능성도 있어요 🥲
앱에서 해당 버튼을 심는 방법은 간단합니다.
@Binding var searchText: String
@Binding var authorizationStatus: CNAuthorizationStatus = .notDetermined
var body: some View {
List {
ForEach(searchResults(for: searchText)) { person in
ResultRow(person)
}
if authorizationStatus == .limited || authorizationStatus == .notDetermined {
ContactAccessButton(queryString: searchText) { identifiers in
let contacts = await fetchContacts(withIdentifiers: identifiers)
dismissSearch(withResult: contacts)
}
}
}
}
해당 코드는 앱에서 연락처 검색 결과를 표시하기 위한 SwiftUI로 구성된 뷰입니다.
해당 뷰엔 앱의 검색 텍스트 필드에 입력된 텍스트에 대한 바인딩이 구성되있죠.
ForEach로 돌려진 부분엔 앱의 자체 데이터에 해당 연락처 데이터를 조회합니다.
만약, 제한된 접근이거나 결정되지 않은 접근 레벨일 경우 ContactAccessButton을 표기하는것이죠.
(물론 조건을 달리하여 표기할 수도 있습니다.)
버튼 초기화 구성 시 검색 필드에 입력한 텍스트를 전달합니다.
그리고 콜백으로 연락처 식별자 문자열 배열을 받죠.
해당 버튼은 View이기에 자유롭게 뷰 모디파이어를 이용해 꾸며줄 수 있습니다.
버튼은 앱이 액세스하기 전에 민감 정보를 표시하기에 버튼의 컨텐츠는 비공개로 유지되지만 앱에는 표시가 됩니다.
또한, 버튼은 검증된 이벤트에만 응답해줍니다.
그리고 컨텐츠를 명확히 읽을 수 있고 장애물이 없는 경우에만 버튼을 탭할 때 액세스가 허용됩니다.
ContactAccessButton에는 이런 프라이빗 디자인이 들어가 있습니다.
딱 그냥 겉만 봐도 명확한 버튼으로 잘 만들었다~ 라는걸 알 수 있죠.
ContactAccessButton은 강력한 개인 정보 보호 기능을 통해서 앱이 추가 액세스 권한을 얻을 수 있는 강력하고 편리한 방법이죠 😀
이제 마지막으로 버튼 외에도 연락처 프레임워크에는 연락처 데이터를 액세스할 수 있는 3가지 다른 방법이 존재합니다.
같이 확인해보시죠! 👯♂️
Accessing contacts
CNContactStore
가장 기본적으로 CNContactStore로 연락처 데이터에 액세스 할 수 있습니다.
연락처를 가져오고 생성할 수 있죠.
앱이 연락처 데이터에 액세스하려고 시도하면 CNContactStore가 자동으로 인증 프롬프트를 띄우고 진행해요.
CNContactStore를 사용해 앱의 인증 레벨을 확인하고 이를 통해 적절한 UI를 표시해줍니다.
여기서는 데이터를 읽고 쓰려면 앱에 승인이 있는 경우에만 가능하죠.
또한, 연락처가 변경되면 이를 알려주고 변경된 내용을 확인하는데 사용할 수 있습니다.
추가로, CNAuthorizationStatus에도 limited가 iOS 18에서부터 추가되었기에 제한된 접근 사용도 가능합니다.
코드 예시로 볼까요?
해당 메서드는 연락처 식별자 문자열 배열을 통해 CNContact 배열을 반환하는 함수입니다.
메인 액터를 차단하지 않고 비동기 작업으로 진행합니다.
Task 내에서는 우선 가져오려는 연락처 필드의 키를 나열하는 CNContactFetchRequest를 생성합니다.
(key와 fetchRequest)
예시에선 연락처 이름을 표시하는데 필요한 이름 필드만 가져옵니다.
그리고 fetchRequest 식별자로 연락처를 가져오기위해 CNContact의 predicateForContacts를 사용해줍니다.
그 후 do catch에서 CNContactStore의 enumerateContacts를 통해 해당 연락처 결과를 배열로 수집합니다.
다음으로 연락처 데이터에 액세스하는 방법은 CNContactPickerViewController를 사용하는것입니다 😀
해당 VC는 연락처 DB에서 하나 이상의 연락처를 선택하기 위한 시스템 UI를 제공해줍니다.
연락처를 선택한 후 앱은 선택한 연락처의 일회성 스냅샷을 수신해줍니다.
해당 VC는 앱의 접근 인증 레벨에 관계없이 작동하고 항상 전체 연락처 DB를 표시해줍니다.
선택에서 하나 이상 연락처가 선택되면 앱은 데이터를 수신받게 됩니다.
CNContactPickerViewController는 이메일 주소 / 전화번호 선택과 같은 일회성 작업을 위한 연락처 정보만 필요한 경우에 가장 적합합니다.
연락처는 일시적으로만 앱과 공유되기 때문이죠.
앞서 초반에 살펴봤듯이, iOS 18에선 앱의 제한된 접근에 대해 변경할 수 있는 모달 시트를 제공하는 Contact Access Picker라는 새로운 피커가 생겼습니다.
만약 여러 추가 연락처에 액세스하려면 Contact Access Picker를 사용하는것도 좋겠죠?
Contact Access Picker는 CNContactStore를 통해 앱이 액세스할 수 있는 연락처를 관리하기 위한것입니다.
즉, 접근에 대한 피커이지 연락처에 대해 가져오는 피커가 아닙니다!
이런식으로 사용할 수 있죠.
연락처에 액세스 하는 방법에 대해 4가지로 정리해볼 수 있습니다.
CNContactPickerViewController는 인증 레벨과 상관없이 작동하고 앱이 VC에서 선택한 연락처에 항상 일회성 접근을 얻도록 허용해줍니다.
CNContactStore는 데이터에 접속하는 기본 게이트웨이이며 승인이 꼭 필요합니다.
앱의 권한이 전체 혹은 제한된 권한이 있을 경우에만 사용할 수 있습니다.
ContactAccessButton은 앱의 인증이 제한되거나 아직 선택되지 않은 경우에만 사용할 수 있습니다.
전체 허용이면 사실 사용할 일이 없죠.
추가 연락처에 대해 접근 허용을 하기 위함이니까요.
즉, 앱의 인증이 제한되었을때 사용하기에 가장 편리하고 좋은 방법이긴 합니다.
contactAccessPicker는 앱의 제한된 액세스를 관리하기 위한것으로 앱에 제한된 권한이 있는 경우에만 사용해야 합니다.
인증 레벨에 따른 연락처 접근에 대한 4가지 방법들을 적절히 사용하면 좋겠죠? 😃
마무리
다른것보다 접근 제한에 대한것과 편리한 ContactAccessButton이 눈에 띄네요.
제한된 접근은 왜 이제야 이렇게 기능을 활성화시키고 했는지 프라이버시를 되게 중요시 하는 애플을 봤을때 조금 의문이긴 했습니다 🥲