CloudKit, Failed to modify some records - Zone Not Found - ios

I'm getting the following error.
ERROR[CKErrorDomain:2] Failed to modify some records,
<CKError 0x1c005e1e0: "Partial Failure" (1011); "Failed to modify some records";
partial errors: {
BB27A0F8-0D8A-4279-A4E6-515B4E6C5116:(MainCustomZone:__defaultOwner__) =
<CKError 0x1c0050740: "Zone Not Found" (26/2036); server message = "Zone 'MainCustomZone'
does not exist"; uuid = E4AE311D-A73F-4F8A-BAF7-1EF5082D2FA9>
}>
My app works fine on my development devices, but in testflight for my beta users they get the error above. When I use a testflight build it still works fine for me, yes I am pointing at the production conatiner in my entitlements I have set the 'com.apple.developer.icloud-container-environment' set to 'production.
I've triple checked that the I'm looking at the correct container and the zone name is spelt correctly.
I have iCloud enabled in my developer account under app id's.
I've also got Write set for authentication, in security roles for each record type.
Please can someone suggest what the problem is?
I've been researching the issue without success.
Here's some typical code to create a zone which I use.
CKFetchRecordChangesOperation *changesOperation = [[CKFetchRecordChangesOperation alloc]
initWithRecordZoneID: [self customZone]
previousServerChangeToken: previousServerChangeToken];
-(CKRecordZoneID*)customZone
{
return [[CKRecordZoneID alloc] initWithZoneName: cCUSTOM_ZONE
ownerName: CKOwnerDefaultName];
}

There is only one zone in a database - the Default zone. If your app is using any other zones, your app must create the zone before attempting to access (or write) any records in the zone.
You probably created the zone in development at some point which is why the code works there.
The screenshot is showing your private database. Every user has their own private database and you can't see the private database of other users in the dashboard. You need to create the zone via code in your app.

Related

SwiftUI Firebase Auth Error "Paths must not contain // in them"

In my SwiftUI app I suddenly started getting this error once my user logs in (I use Firebase Phone Auth)". It happens right as soon as I do this:
let db = Firestore.firestore()
db.collection("user").document(user.UID)
.getDocument { document, err in
This is the error, the app crashes totally:
Invalid path (com.googleusercontent.apps.178114301509-gvnp7pp9tm6jq9s4rridgoae9glog8nj://firebaseauth/link?deep_link_id=https%3A%2F%2Fgigas-4f2dd.firebaseapp.com%2F__%2Fauth%2Fcallback%3FauthType%3DverifyApp%26recaptchaToken%3DTOKEN%26eventId%3Dmwkcoldfan). Paths must not contain // in them."
I tried reverting back my project with Github but I cannot find whatever happened that started all this. I don't even know what Path is the debugger talking about. I have seen people in other cases saying that maybe it is the id being empty so a / and another / collapse into a // making it causing such an error but it is not my case since I am sure the id is not empty.

CloudKit CKQueryOperation error "SharedDB does not support Zone Wide queries" querying CKContainer.sharedCloudDatabase in iOS

I received an error in CKQueryOperation.queryResultBlock that says "SharedDB does not support Zone Wide queries" in the Xcode debug window when I print(error.localizedDescription), when my code does a query in the CKContainer.sharedCloudDatabase. The owner of the share gave read and write permission to share the share only with people the owner added in the UICloudSharingController.
Here are the significant code that queries the shared database:
queryOperation.queuePriority = .veryHigh
queryOperation.qualityOfService = .userInteractive
sharedCloudDatabase.add(queryOwnerGroupIdentifierOperation)
queryOperation.waitUntilFinished()

Multiple user Video Call using WebRTC SDK Directly

Hi I am working on a Video Call Solution by using WebRTC directly. I have achieved 1-1 video call using firebase as Signaling service and using default google ICE Servers.
Core Req: Multiple users with in a Room using WebRTC at least 4 users using the default ice/stun servers available. I'm using pod 'GoogleWebRTC'
Issue comes when multiple users joins the same room ID.
So, I am maintaining Peerconnection reference as this
var peerConnection: RTCPeerConnection! = nil
When a new user i.e., remote user joins I set its description as below
self.peerConnection.setRemoteDescription(offer, completionHandler: {(error: Error?) in
if error == nil {
LOG("setRemoteDescription(offer) succsess")
self.makeAnswer() // Create Answer if setRemoteDescription succeeds
} else {
LOG("setRemoteDescription(offer) ERROR: " + error.debugDescription)
}
})
What I feel ? Issue is when third user joins again I set the remote Description with above mentioned code which makes my previous video stops to render sometimes or most of the times.
I looked for solutions and found need to maintain multiple peer connection references, but how? Any help with my requirement will be appreciated.
Just give me clue or sample code will be really great.
In case of multiple user call you should have multiple peerconnections, because it's isn't possible to set different sdps to one pc.
So you can use something like this
var peerConnectionMap = [String: RTCPeerConnection]()
Where String here is some constant user id.
When new user is joined to the room, then you create new pc and store it in this dictionary. Then you exchange with sdps as usual.
Don't forget that you should reuse local audio-video track created when first peerconnection is created.

Trying to use Realm Object Server Tutorial

I have created an Amazon Web Services EC2 instance and deploy one of the AMIs with a Realm Object Server as its documentation explains:
https://realm.io/docs/realm-object-server/#install-realm-object-server
Once installed and created my admin user, I have completed the iOS tutorial: https://realm.io/docs/tutorials/realmtasks/, just until point 7, enough for creating task, but when I add new task in app, nothing happens. Debugging, I notice that next sentence try, is not executing:
let items = self.items
try! items.realm?.write {
items.insert(Task(value: ["text": text]), at: items.filter("completed = false").count)
}
The items collection seems to be initialized properly:
In the ROS dashboard, can see the database referenced in Xcode:
In image can be see "Default permissions" property is no access, is this the reason of not creating new task? If so, how can I change that permissions? If that is not the reason, anyone could help me?
thanks in advance
The problem was that I did not follow al the complete tutorial because I do not want to use the desktop application, just mobile example, but realm init objects in desktop app, so I never got a valid realm where perform actions.
For a quick and simple start with this realm tutorial pointing to an online server, not local, you must initialize the TaskList object and add it to self.realm on setup
// Show initial tasks
func updateList() {
if self.realm.objects(TaskList.self).count == 0 {
let list = TaskList()
list.id = "000001"
list.text = "lista de prueba"
// Add to the Realm inside a transaction
try! self.realm.write {
self.realm.add(list)
}
}
if self.items.realm == nil, let list = self.realm.objects(TaskList.self).first {
self.items = list.items
}
self.tableView.reloadData()
}
checking if there is not a TaskList with if self.realm.objects(TaskList.self).count == 0 {, you can create one and init realm.
You probably forgot to launch Mac demo app first or login with a different user. The tutorial assumes that existing data will be synced at login. If you have never launched the Mac app or logged in a different user, it may happen that items are not managed by Realm.
The tutorial says the following:
First, please follow the Get Started instructions to get set up with the Realm Mobile Platform and to launch the macOS version of RealmTasks.
Also, you attempt to try this tutorial with ROS on AWS. The tutorial assumes running ROS on a same local machine.
So you should modify the Mac app code to connect to the AWS, then run it to synchronize the initial data. Then run the tutorial iOS app.
The default permissions here show whether all other users can access the Realm or not, which isn't the case here. We already have an internal issue around clarifying this.
The registered user who owns the Realm has individual permissions to it by default. If you wouldn't have permissions opening the synchronized Realm from the client would also fail because of insufficient permissions, so this isn't the problem here.
So going back to your code:
try! items.realm?.write { … }
My guess would be that the problem here is that the collection isn't already attached to a Realm, so that items.realm? evaluates to null. In that case the write transaction wouldn't be executed.
You can resolve this by making sure to add the items first to a Realm or executing the write directly on a synchronized Realm.

iOS 7+: Unique identifier per device<->Store-ID (user) combination

I've spent two days no reading and testing as there is a lot of info about this topic.
Unfortunately I've found no solution yet. I can't implement my own authentication as this doesn't help with the issue I want to solve (see Backgrounding at the end of the question).
Here is my current best approach:
I'm generating a UUID thanks to https://stackoverflow.com/a/8677177/1443733 and storing it in the KeyChain as suggested with SwiftKeychainWrapper (https://github.com/jrendel/SwiftKeychainWrapper)
The short nice and sweet code for that is:
let stored = KeychainWrapper.stringForKey("UUID")
if stored != nil {
Helper.log(TAG, msg: "retrieved from keychain: \(stored!)")
} else {
let theUUID = CFUUIDCreate(nil)
let str = CFUUIDCreateString(nil, theUUID)
Helper.log(TAG, msg: "generated UUID: \(str)")
let ret = KeychainWrapper.setString(str, forKey: "UUID")
Helper.log(TAG, msg: "setkeychain: \(ret)")
}
But the UUID stored in the keychain seems to be per device and not per store ID as well.
When I store the UUID like above and login with a different Store ID on the device KeychainWrapper.stringForKey("UUID")still returns the value of the other user.
Isn't their a way to store a value in a store-id keychain?
It seems that I'm so close so I hope someone could point me in the right direction.
If that approach (with a keychain) can't succeed please let me know as well.
I reckon you can ask a different question as well: Is there some cryptic data I can read/generate or a store which changes with the Store Id currently used on a device?
Ohh... and Swift examples preffered ;)
Backgroundinfo:
I use IAPs in my app and want to save the Store-Id of the user once a refresh of the receipt is valid.
On each start of the app I check if the current Store-Id is the same as the saved one. If not I trigger immediately a refresh of the receipt. If it fails I fall back to the free version of the app.
iOS devices do not support multiple users.
If you want to differentiate between users you will have to do that in your app, perhaps with a user login. Then save a UUID per userID in the Keychain.
As NSUserdefaults temporarily stores the UUID.so,after unistalling the app and again installing,the UID changes. So, UUID must be stored in keychain

Resources