Похоже, у вас здесь много проблем. Я бы порекомендовал внимательно изучить UICloudSharingController документация .
Первая проблема в том коде, который вы предоставили, вы создаете новый общий ресурс каждый раз, когда вам нужно создать его один раз, а затем показать этот общий ресурс в любое время, когда вы захотите с ним работать (включая получение URL ресурса). После создания общего ресурса вы, вероятно, захотите как-то сохранить это на устройстве (это может быть так же просто, как сохранить его в UserDefaults).
Вторая проблема заключается в том, что, похоже, вы неправильно создаете экземпляр UICloudSharingController. При первоначальном создании CKShare необходимо использовать инициализатор UICloudSharingController init (prepHandler:) и создать общий ресурс ВНУТРИ этого.
Согласно документации для различных инициализаторов (выделено мое):
Важно
Вы должны инициализировать контроллер с правильным инициализатором
Метод . Не используйте init (prepareHandler :), если CKRecord
уже поделился. Аналогично, не используйте init (share: container :), если
CKRecord не является общим. Использование неправильного инициализатора приводит к ошибкам
при сохранении записи.
А затем, когда вы хотите показать shareSheet, вы используете UICloudSharingController init (share: container:) инициализатора и передаете ему общий ресурс, который вы сохранили на устройстве.
Вот код, предоставленный в документации UICloudSharingController для создания CKShare:
func presentCloudSharingController(_ sender: Any) { guard
let barButtonItem = sender as? UIBarButtonItem,
let rootRecord = self.recordToShare else {
return
}
let cloudSharingController = UICloudSharingController { [weak self] (controller, completion: @escaping (CKShare?, CKContainer?, Error?) -> Void) in
guard let `self` = self else {
return
}
self.share(rootRecord: rootRecord, completion: completion)
}
if let popover = cloudSharingController.popoverPresentationController {
popover.barButtonItem = barButtonItem
}
self.present(cloudSharingController, animated: true) {}
}
func share(rootRecord: CKRecord, completion: @escaping (CKShare?, CKContainer?, Error?) -> Void) {
let shareRecord = CKShare(rootRecord: rootRecord)
let recordsToSave = [rootRecord, shareRecord];
let container = CKContainer.default()
let privateDatabase = container.privateCloudDatabase
let operation = CKModifyRecordsOperation(recordsToSave: recordsToSave, recordIDsToDelete: [])
operation.perRecordCompletionBlock = { (record, error) in
if let error = error {
print("CloudKit error: \(error.localizedDescription)")
}
}
operation.modifyRecordsCompletionBlock = { (savedRecords, deletedRecordIDs, error) in
if let error = error {
completion(nil, nil, error)
} else {
completion(shareRecord, container, nil)
}
}
privateDatabase.add(operation)
}
И в следующий раз, когда вы захотите показать это, это будет гораздо прямолинейнее:
let share = // yourCKShare
let container = // yourCKContainer
let viewController = // yourViewController
let shareController = UICloudSharingController(share: share, container: container)
viewController.present(shareController, animated: true)
И, наконец, чтобы ответить на часть URL вашего вопроса, UICloudSharingController используется для общего доступа - в то время как контроллер представляет общий ресурс, есть кнопка «Копировать ссылку», доступная владельцу (и, возможно, пользователю, если Вы разрешаете публичный доступ - я не смотрел на это, так как мои вещи являются частными):