Я хотел бы сохранить не более одной записи (т.е. рейтинга) для каждого пользователя в таблице общедоступной базы данных. Для этого мне нужно сохранить текущий идентификатор пользователя или идентификатор устройства. Но как я могу получить это?
Как получить текущий идентификатор пользователя в CloudKit?
Ответы (4)
Вы можете вызвать -[CKContainer fetchUserRecordIDWithCompletionHandler:]
для получения идентификатора текущей записи пользователя:
Получите идентификатор iCloud ID / идентификатор записи CloudKit с помощью Swift 2
Вот фрагмент, который я всегда использую для получения идентификатора iCloud пользователя iPhone (Apple называет его идентификатором записи CloudKit) для приложения iOS.
Единственное, что вам нужно сделать в Xcode, это активировать флажок «CloudKit» в возможностях iCloud вашего проекта. Вам вообще не нужно активно использовать CloudKit — это просто ядро всех действий iCloud, начиная с iOS 8.
Важно знать, что Apple никогда напрямую не раскрывает реальный идентификатор iCloud, а всегда просто возвращает защищенный хэш идентификатора iCloud и идентификатора вашего приложения. Но это не должно вас беспокоить, потому что эта строка по-прежнему уникальна для каждого пользователя вашего приложения на всех его устройствах и может использоваться в качестве замены логина.
Моя функция является асинхронной и возвращает необязательный объект CKRecordID. Наиболее интересным свойством этого объекта CKRecordID является имя_записи.
CKRecordID.recordName
— это строка из 33 символов, где первым символом всегда является символ подчеркивания, за которым следуют 32 уникальных символа (== ваш пользовательский идентификатор iCloud, закодированный для вашего приложения). Похоже на: "_cd2f38d1db30d2fe80df12c89f463a9e"
import CloudKit
/// async gets iCloud record name of logged-in user
func iCloudUserIDAsync(complete: (instance: CKRecordID?, error: NSError?) -> ()) {
let container = CKContainer.defaultContainer()
container.fetchUserRecordIDWithCompletionHandler() {
recordID, error in
if error != nil {
print(error!.localizedDescription)
complete(instance: nil, error: error)
} else {
print("fetched ID \(recordID?.recordName)")
complete(instance: recordID, error: nil)
}
}
}
// call the function above in the following way:
// (userID is the string you are intersted in!)
iCloudUserIDAsync() {
recordID, error in
if let userID = recordID?.recordName {
print("received iCloudID \(userID)")
} else {
print("Fetched iCloudID was nil")
}
}
Вот фрагмент кода для Swift 3
import CloudKit
/// async gets iCloud record ID object of logged-in iCloud user
func iCloudUserIDAsync(complete: @escaping (_ instance: CKRecordID?, _ error: NSError?) -> ()) {
let container = CKContainer.default()
container.fetchUserRecordID() {
recordID, error in
if error != nil {
print(error!.localizedDescription)
complete(nil, error as NSError?)
} else {
print("fetched ID \(recordID?.recordName)")
complete(recordID, nil)
}
}
}
// call the function above in the following way:
// (userID is the string you are interested in!)
iCloudUserIDAsync { (recordID: CKRecordID?, error: NSError?) in
if let userID = recordID?.recordName {
print("received iCloudID \(userID)")
} else {
print("Fetched iCloudID was nil")
}
}
Более компактное кодовое решение Swift 5:
CKContainer.default().fetchUserRecordID(completionHandler: { (recordId, error) in
if let name = recordId?.recordName {
print("iCloud ID: " + name)
}
else if let error = error {
print(error.localizedDescription)
}
})
Для конкретного контейнера CloudKit используйте этот код:
CKContainer(identifier: "<Your CloudKit container identifier>").fetchUserRecordID(completionHandler: { (recordId, error) in
if let name = recordId?.recordName {
print("iCloud ID: " + name)
}
else if let error = error {
print(error.localizedDescription)
}
})