Post not yet marked as solved
I have timer based code running perfectly when the app is running. Both the timer based functions get called and I am able to access and update iCloud. But if accidentally app goes off-line or user kills it, the timer code cannot be invoked. Is there a off-line mechanism, or some technique anyone can suggest that will allow to recollect and invoke pre-defined timer calls and execute the associated code?
let currentDateTime = Date()
let calendar = Calendar.current
var tempDateTime1 = calendar.date(byAdding: .minute, value: 1, to: currentDateTime)
var tempDateTime2 = calendar.date(byAdding: .minute, value: 2, to: currentDateTime)
DispatchQueue.main.async {
let userInfo:Dictionary<String, String> = ["tag": orderCkRecordName]
let startTimer = Timer(fireAt: tempDateTime1!, interval: 0.0, target: self, selector: #selector(self.beginOrderUpdate(sender:)), userInfo: userInfo as Dictionary, repeats: false)
let endTimer = Timer(fireAt: tempDateTime2!, interval: 0.0, target: self, selector: #selector(self.endOrderUpdate(sender:)), userInfo: userInfo as Dictionary, repeats: false)
RunLoop.current.add(startTimer, forMode: RunLoopMode.commonModes)
RunLoop.current.add(endTimer, forMode: RunLoopMode.commonModes)
}
Post not yet marked as solved
Upgraded ios 13.6 and changed bundle identifier and container name. Created CKDatabaseSubscription for both public and shared database and can see in cloudkit dashboard. Both didFinishLaunchingWithOptions and didRegisterForRemoteNotificationsWithDeviceToken get called in AppDelegate.
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound], completionHandler: { granted, error in
guard granted else { return }
DispatchQueue.main.async {
application.registerForRemoteNotifications()
print("Registered for Remote notifications")
}
})
return true
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data){
let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
let token = tokenParts.joined()
print("Device Token: \(token)")
})
self.iCloudSubscribeToPrivateDB()
self.iCloudSubscribeToSharedDB()
}
In the project both background fetch and remote notifications are enabled. I make databases changes in cloudkit dashboard, but push notifications are not being sent. They were working now just stopped after I made the above changes. What could be wrong?
Post not yet marked as solved
in Cloudkit Dashboard, I select Record Type, Edit Indexes, then I select Add Basic Index. I see createTime, createdBy, eTag, modTime, modifiedBy, recordID. I do not see recordName. Without creating index on recordName, I cannot query the record in cloudKit Dashboard. How to create index on recordName??
Post not yet marked as solved
I drag a scroll view and then set constraint 0 on all four directions. I cannot activate update frame. Gives error ScrollView has ambiguous scalable content width and height
Post not yet marked as solved
while presenting the UICloudSharingController on top of a view, it presents the screen and when I select the messages option to send a message to a person whom I want to share with, it gives a spinning wheel with "uploading" message and vanishes.
However when I go to cloudkit dashboard the root record has been shared. But I cannot share it with specific person. Is it because it has shared global? How can I fix it?
self.shareInfraRecord(zoneID: appDelegate.privateContactZoneID, completion: { (status) in
		 if ( status == false) {
						 return
			}
		})
func shareInfraRecord(zoneID: CKRecordZone.ID, completion: @escaping(Bool) -> Void) {
		if let rootRecord = self.rootRecord {
				if self.rootRecord?.share == nil {
						let sharingController = UICloudSharingController { (controller, preparationHandler: @escaping (CKShare?, CKContainer?, Error?) -> Void) in
								
								let shareID = CKRecord.ID(recordName: UUID().uuidString, zoneID: zoneID)
								var share = CKShare(rootRecord: rootRecord, shareID: shareID)
							
								share[CKShare.SystemFieldKey.title] = Cloud.ShareInfrastructure.ContactShareTitleKey as CKRecordValue?
								share[CKShare.SystemFieldKey.shareType] = Cloud.ShareInfrastructure.ContactShareTypeKey as CKRecordValue?
							
								let modifyRecZoneOp = CKModifyRecordsOperation(recordsToSave:[rootRecord, share], recordIDsToDelete: nil)
								modifyRecZoneOp.modifyRecordsCompletionBlock = { (records, recordID, error) in
										if error != nil {
												if let ckerror = error as? CKError {
														if let serverVersion = ckerror.serverRecord as? CKShare {
																share = serverVersion
														}
														completion(false)
												}
										}
										preparationHandler(share, self.defaultContainer, error)
								}
								self.privateDB?.add(modifyRecZoneOp)
						}
Post not yet marked as solved
I have only one phone and Apple ID. I want to test CKShare between two users. Do I need two phones? Do I need two different Apple IDs? I read that two Apple IDs cannot share same phone. Can someone tell me what is the best way to test CKShare between two users on my development environment
Post not yet marked as solved
I create a share and the shared URL is successfully created
let share = CKShare(rootRecord: infraRecord)
// save
let op: CKFetchShareParticipantsOperation = CKFetchShareParticipantsOperation(userIdentityLookupInfos: lookupInfos)
op.fetchShareParticipantsCompletionBlock = { error in
if let error = error {
print("error: ", error)
completion(false, error)
}
}
op.shareParticipantFetchedBlock = { participant in
participant.permission = .readOnly
share.addParticipant(participant)
let modOp: CKModifyRecordsOperation = CKModifyRecordsOperation(recordsToSave: [infraRecord, share], recordIDsToDelete: nil)
modOp.savePolicy = .ifServerRecordUnchanged
modOp.perRecordCompletionBlock = {record, error in
print("record completion \(record) and \(String(describing: error))")
}
modOp.modifyRecordsCompletionBlock = {records, recordIDs, error in
if let error = error {
print("error in modifying the records: ", error)
}
else if let anURL = share.url {
// update the location CKRecord with share URL
self.updateLocationPublicRecord(withShareUrl: anURL.absoluteString, locationRecord: locationRecord, completion: { (status, error) in
if let error = error {
print("error: ", error)
}
})
print("share url \(String(describing: share.url))")
}
completion(true, nil)
}
self.privateDB?.add(modOp)
//completion(true, nil)
}
self.defaultContainer?.add(op)
To access the share I first try to get the recordzones from shared database
func getRecordZones(completion: @escaping (CKRecordZoneID?, Error?) -> Void) {
self.sharedDB?.fetchAllRecordZones(completionHandler: { (ckrecordZones, error) in
guard error == nil else {
if let ckError = error as? CKError {
self.aErrorHandler.handleCkError(ckerror: ckError)
}
completion (nil, error)
return
}
if let recordZones = ckrecordZones {
for i in 0 ..< recordZones.count{
// find the zone you want to query
if recordZones[i].zoneID.zoneName == Cloud.SharedZone.UserProfile.ZoneName {
completion (recordZones[i].zoneID, nil)
}
}
}
})
}
```
I dont get any recordzones from shared database. When I go to cloudkit dashboard, I don't see any shared zones in the shared database. Why is it that shared record zone does not exist? how to make this work?