I am trying to utilize CloudKit
in my iOS application, but when I attempt to create a new record for for a User
record type (record type is named Users
), I get this error:
<CKError 0x7fb80947ffb0: "Permission Failure" (10/2007);
server message = "CREATE operation not permitted";
uuid = 8C4C7B60-E3F4-42FC-9551-D3A76A6FF9D6;
container ID = "iCloud.com.jojodmo.Blix">
To create the new record, I am using this code in viewDidLoad()
:
UserCKManager.create(
CloudKitUser(
email: "email@website.com", password: "password", salt: "1AF4E759B20FEC32",
username: "jojodmo", posts: [], biography: "This is my bio",
firstName: "John", lastName: "Doe", flags: [],
profilePicture: UIImage(), downVotesGiven: 1, downVotesRecieved: 2,
upVotesGiven: 3, upVotesRecieved: 4, pictureProvided: false), callback: nil)
Which creates a new CloudKitUser
:
init(email: String, password: String, salt: String, username: String, posts: [String], biography: String, firstName: String, lastName: String, flags: [String], profilePicture: UIImage, downVotesGiven: Int, downVotesRecieved: Int, upVotesGiven: Int, upVotesRecieved: Int, pictureProvided: Bool){
self.ready = false
record = CKRecord(recordType: "Users")
self.email = email
self.password = password
self.salt = salt
self.username = username
self.posts = posts
self.biography = biography
self.firstName = firstName
self.lastName = lastName
self.flags = flags
self.profilePicture = profilePicture
self.downVotesGiven = downVotesGiven
self.downVotesRecieved = downVotesRecieved
self.upVotesGiven = upVotesGiven
self.upVotesRecieved = upVotesRecieved
self.pictureProvided = pictureProvided
self.ready = true
}
And then attempts to create a record with it:
class func create(user: User, callback: ((success: Bool, user: User?) -> ())?){
let ckUser = CloudKitUser(user: user)
//I've also tried using CKContainer.defaultContainer().privateCloudDatabase, and I get the same error
CKContainer.defaultContainer().publicCloudDatabase.saveRecord(ckUser.record){(record, error) in
if(error != nil){
println("An error occurred: \(error)")
callback?(success: false, user: nil)
}
else{
println("Record saved successfully")
callback?(success: true, user: ckUser)
}
}
}
I know it isn't a problem with connecting to the database, because I have already gotten an error saying that there was no container with the ID I had given, which I fixed.
I am trying to run this on the iOS
simulator (I am signed into iCloud on it)
Users is a special recordType that already exist in CloudKit. You should not create records yourself. Records will be automatically created for new users that are using your app. You also can't create subscriptions and query the Users recordtype. You can only query Users records directly by ID. You can store extra data in the Users recordType, but I think in your case it would be better if you named your record type something else.
In addition to Edwin's answer, it's entirely feasible to save custom fields to the public
Users
recordType, but you need to retrieve theCKRecordID
for the user first (viaCKContainer
fetchUserRecordID()
ordiscoverUserIdentity()
) and then build theCKRecord
onUsers
using that ID.Also, if you're using
CKModifyRecordsOperation
make sure thesavePolicy
is set to.changedKeys
in order to allow the update to go through.