我尝试从 CloudKit 检索当前用户的名字和姓氏。但是,我收到了来自 Xcode 的消息,表明“userDiscoverability”功能将在 iOS 17.0 中被弃用。不再支持此功能,相反,我应该考虑使用“与其他 iCloud 用户共享 CloudKit 数据”功能。
这是我一直在使用的功能:
func fetchUserName(completion: @escaping ( _ fullName:String, _ success:Bool) -> Void) {
container.requestApplicationPermission(.userDiscoverability) { (status, error) in
self.container.fetchUserRecordID { (record, error) in
self.container.discoverUserIdentity(withUserRecordID: record!) { (userID, error) in
var name: String = ""
self.container.accountStatus { accountStatus, error in
if let error = error {
print(error.localizedDescription)
}
}
guard let givenName = userID?.nameComponents?.givenName,
let familyName = userID?.nameComponents?.familyName else {
completion("", false)
print("Unable to fetch user name")
return
}
let fullName: String = givenName + " " + familyName
name = fullName
DispatchQueue.main.async {
completion(name, true)
}
}
}
}
}
有人有解决这个问题的方法吗?
您不再需要外部调用(
container.requestApplicationPermission
)。
为了检索名称,您需要首先获取活动用户记录 ID,然后使用该 ID 获取共享参与者,最后从 CKShare.Participant 对象中检索名称。你的代码已经做到了这一点,它的修改版本看起来像:
func fetchUserName(completion: @escaping ( _ fullName:String, _ success:Bool) -> Void) {
self.container.fetchUserRecordID { (record, error) in
self.container.fetchShareParticipant(withUserRecordID: record!) { (userID, error) in
var name: String = ""
self.container.accountStatus { accountStatus, error in
if let error = error {
print(error.localizedDescription)
}
}
guard let givenName = userID?.nameComponents?.givenName,
let familyName = userID?.nameComponents?.familyName else {
completion("", false)
print("Unable to fetch user name")
return
}
let fullName: String = givenName + " " + familyName
name = fullName
DispatchQueue.main.async {
completion(name, true)
}
}
}
}
如果尚未启用,您还需要在您的应用程序中启用 CloudKit。
static func getUserInformation() async throws -> (id: String, name: String) {
do {
let recordID = try await container.userRecordID()
let id = recordID.recordName
let participant = try await container.shareParticipant(forUserRecordID: recordID)
guard let nameComponents = participant.userIdentity.nameComponents else {
throw CloudKitError.userIdentityUnknownName
}
let name = PersonNameComponentsFormatter().string(from: nameComponents)
return (id, name)
} catch {
throw error
}
}
userIdentity.nameComponents
未能为我返回值,但我发现使用
CKShare
直接有效:
func fetchCurrentUsername(for share: CKShare) -> String {
var name = ""
let currentUser = share.currentUserParticipant
if let nameComponents = currentUser?.userIdentity.nameComponents {
name = nameComponents.formatted()
}
return name
}
调查Apple的示例项目在iCloud用户之间共享核心数据对象让我找到了这个解决方案。它有大量有用的信息。