Как получить текущий идентификатор пользователя в CloudKit?

Я хотел бы сохранить не более одной записи (т.е. рейтинга) для каждого пользователя в таблице общедоступной базы данных. Для этого мне нужно сохранить текущий идентификатор пользователя или идентификатор устройства. Но как я могу получить это?


person Jan F.    schedule 28.03.2015    source источник
comment
stackoverflow.com/a/55594874/1522584   -  person Abhijith    schedule 09.04.2019


Ответы (4)


Вы можете вызвать -[CKContainer fetchUserRecordIDWithCompletionHandler:] для получения идентификатора текущей записи пользователя:

person farktronix    schedule 28.03.2015
comment
Я получаю исключение, когда делаю CKContainer.defaultContainer() libc++abi.dylib: завершение с необработанным исключением типа CKException - person Mukul More; 09.03.2018

Получите идентификатор 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")
    }
}
person Sebastian    schedule 27.11.2015
comment
Я получаю исключение, когда делаю CKContainer.defaultContainer() libc++abi.dylib: завершение с необработанным исключением типа CKException - person Mukul More; 09.03.2018
comment
@Sebastian Могу ли я использовать этот идентификатор записи для уникальной идентификации пользователя с одной и той же учетной записью icloud на разных устройствах? Я имею в виду, если пользователь устанавливает приложение и пишет какие-то заметки. Затем я сохраняю эти заметки в firebase. И затем этот пользователь устанавливает приложение на другое устройство с той же учетной записью icloud, могу ли я получить заметки, уже написанные на другом устройстве? - person Salman Ali; 13.05.2018
comment
@SalmanAli Да, и это один из самых важных аспектов. Я написал об этом сообщение в блоге несколько лет назад: medium.com/ @skreutzb/ - person Sebastian; 14.05.2018
comment
@Sebastian иногда возвращаемое имя записи равно нулю, и выход и повторный вход в icloud решает проблему, но есть ли какая-либо причина или лучшее программное решение для этой проблемы. - person Daniel Raouf; 18.07.2018

Вот фрагмент кода для 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")
    }
}
person Yi-Hsiu Lee    schedule 09.12.2016
comment
я получил сообщение об ошибке, например, Завершение работы приложения из-за необработанного исключения «CKException», причина: «В приложении отсутствуют необходимые права com.apple.developer.icloud-services» - person RejoylinLokeshwaran; 25.11.2017
comment
Вы включаете iCloud на вкладке «Возможности»? - person Yi-Hsiu Lee; 25.11.2017
comment
@Yi-HsiuLee Могу ли я использовать этот идентификатор записи для уникальной идентификации пользователя с одной и той же учетной записью icloud на разных устройствах? Я имею в виду, если пользователь устанавливает приложение и пишет какие-то заметки. Затем я сохраняю эти заметки в firebase. И затем этот пользователь устанавливает приложение на другое устройство с той же учетной записью icloud, могу ли я получить заметки, уже написанные на другом устройстве? - person Salman Ali; 13.05.2018

Более компактное кодовое решение 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)
    }
})
person Ely    schedule 25.04.2020
comment
По какой-то причине это возвращает мне ошибку: Не удалось получить конфигурацию контейнера с сервера для контейнера iCloud.com.my_container_name. Есть идеи, почему? У меня есть пользовательские записи в типе записи «Пользователи», отображаемые на панели инструментов Cloudkit. - person mumush; 14.11.2020