Инициализация называется встроенной по сравнению с перерывами в нагрузке - PullRequest
0 голосов
/ 16 февраля 2020

Чтобы решить эту проблему, я создал новый проект и тщательно копировал один кодовый файл за раз, чтобы изолировать, в чем проблема. Я наконец нашел его, и он приписал этой одной строке кода

CKService().share(rootController: self, result:record)

против

let ck = CKService()   //this line put into the controller class's stored property
///... and then later in the controller
ckService().share(rootController: self, result:record)

В первом случае UICloudSharingController от Apple сломается. Во втором случае UICloudSharingController будет работать.

func share(rootController: UIViewController, result: CKRecord) {
   DispatchQueue.main.async {
            self.container.prepareSharingController(rootRecord: result,
                database: self.databases[0].cloudKitDB,
                zone: self.zone,
                completionHandler: { controller in
                    guard let sharingController = controller else {

                        let title = "Failed to share."
                        let message = "Can't set up a valid share object."
                        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)

                        alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
                        controller?.present(alert, animated: true) { }

                        return
                    }

                    // Save the root record for being used in UICloudSharingControllerDelegate methods,
                    // and presentt the UICloudSharingController.
                    //

                    self.record = result
                    sharingController.delegate = self
                    sharingController.availablePermissions = [.allowPublic, .allowPrivate, .allowReadOnly, .allowReadWrite]
                    rootController.present(sharingController, animated: true) { }
                }
            )
        }
}

И вот часть для prepareSharingController (но я не думаю, что это актуально, потому что этот код просто скопирован / вставлен из примера проекта Apple). Кроме того, код там технически не вызывается, пока пользователь не подтвердит на следующем экране)

func prepareSharingController( rootRecord: CKRecord, participantLookupInfos: [CKUserIdentity.LookupInfo]? = nil,
                                   database: CKDatabase, zone: CKRecordZone,
                                   completionHandler:@escaping (UICloudSharingController?) -> Void) {
        let operationQueue = OperationQueue()
        operationQueue.maxConcurrentOperationCount = 1

        // Share setup: fetch the share if the root record has been shared, or create a new one.
        //
        var sharingController: UICloudSharingController? = nil
        var share: CKShare! = nil

        if let shareRef = rootRecord.share {
            // Fetch CKShare record if the root record has alreaad shared.
            //
            let fetchRecordsOp = CKFetchRecordsOperation(recordIDs: [shareRef.recordID])
            fetchRecordsOp.fetchRecordsCompletionBlock = {recordsByRecordID, error in

                guard handleCloudKitError(error, operation: .fetchRecords, affectedObjects: [shareRef.recordID]) == nil,
                    let result = recordsByRecordID?[shareRef.recordID] as? CKShare else { return }

                share = result

                if let lookupInfos = participantLookupInfos {
                    self.addParticipants(to: share, lookupInfos: lookupInfos, operationQueue: operationQueue)
                }
            }
            fetchRecordsOp.database = database
            operationQueue.addOperation(fetchRecordsOp)

            // Wait until all operation are finished.
            // If share is still nil when all operations done, then there are errors.
            //
            operationQueue.waitUntilAllOperationsAreFinished()

            if let share = share {
                sharingController = UICloudSharingController(share: share, container: self)
            }

        } else {

            sharingController = UICloudSharingController { (_, prepareCompletionHandler) in

                let shareID = CKRecord.ID(recordName: UUID().uuidString, zoneID: zone.zoneID)
                share = CKShare(rootRecord: rootRecord, shareID: shareID)
                share[CKShare.SystemFieldKey.title] = rootRecord.value(forKey: "CD_name") as? CKRecordValue
                //share.publicPermission = .none // default value.

                // addParticipants is asynchronous, but will be executed before modifyRecordsOp because
                // the operationqueue is serial.
                //
                if let lookupInfos = participantLookupInfos {
                    self.addParticipants(to: share, lookupInfos: lookupInfos, operationQueue: operationQueue)
                }

                // Clear the parent property because root record is now sharing independently.
                // Restore it when the sharing is stoped if necessary (cloudSharingControllerDidStopSharing).
                //
                rootRecord.parent = nil

                let modifyRecordsOp = CKModifyRecordsOperation(recordsToSave: [share, rootRecord], recordIDsToDelete: nil)
                modifyRecordsOp.modifyRecordsCompletionBlock = { records, recordIDs, error in

                    // Use the serverRecord when a partial failure caused by .serverRecordChanged occurs.
                    // Let UICloudSharingController handle the other error, until failedToSaveShareWithError is called.
                    //
                    if let ckError = handleCloudKitError(error, operation: .modifyRecords, affectedObjects: [shareID]) {
                        if let serverVersion = ckError.serverRecord as? CKShare {
                            share = serverVersion
                        }
                    }
                    prepareCompletionHandler(share, self, error)
                }
                modifyRecordsOp.database = database
                operationQueue.addOperation(modifyRecordsOp)
            }
        }
        completionHandler(sharingController)
    }

И, наконец, когда я говорю break , я говорю, что UICloudSharingController представленное не будет работать правильно, методы делегата не будут вызваны для UICloudSharingControllerDelegate, а также пользовательский интерфейс, показывающий имя общего ресурса, будет неправильным.

Я не могу понять, чем отличаются эти две строки. У них обоих есть полный объект CKService.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...