New CKRecord in custom zone

I'm wondering if it's possible to save a new CKRecord to a custom zone and have iCloud automatically generate a record ID. I have my zones set up as I'd like. But if I save a new record to iCloud with the CKDatabase.save method, it saves it to the default zone, which is not where I want to save it. If I use a CKModifyRecordsOperation to save the record to its custom zone, it appears I first need to fully construct a CKRecord including a pre-defined record ID, and iCloud uses that record ID rather than generating one. Is there any way of achieving both of my goals other than auto-generating my own unique ID for each record?

Replies

Can't you construct the record without specifying a recordID?

There is no way that I see to set the zone for a CKRecord without setting the zone on the recordID that you use in the CKRecord init method variant that takes a recordID. If you use the init method that only sets the recordType, the record is saved to the default zone. The only apparent option is to use a deprecated convenience initializer that accepts a zone ID, but I consider that a non-starter.

I believe your question is answered here:

https://developer.apple.com/documentation/cloudkit/ckrecord/1462202-initwithrecordtype?language=objc

That’s the deprecated method I mentioned in my previous reply.

Check again. It's not deprecated in my browser.

When using it in code, Xcode 10.1 displays a deprecation warning. In the Dash documentation browser it is marked as deprecated. I'm taking those two indications as evidence that it is indeed no longer to be used in a new code base.

I am looking at this Apple source document (not the Dash equivalent):

https://developer.apple.com/documentation/cloudkit/ckrecord/1462202-initwithrecordtype?language=objc

and it does not say 'deprecated'.


I am using Xcode 10.0 and have the following command:

           CKRecord *aRecord=[[CKRecord alloc] initWithRecordType:theType];


and there is no indication of deprecated.


Are we talking about the same command?

It looks like we are talking about the same method, but different documentation.


I just examined the header file for CKRecord, and that method is displayed (in Xcode 10.1) as:


@available(swift, introduced: 4.2, deprecated: 4.2, message: "Use init(recordType:recordID:) + CKRecord.ID(zoneID:) instead")

public convenience init(recordType: CKRecord.RecordType, zoneID: CKRecordZone.ID)

Seems like you have two choices:

1) switch to ObjectiveC, it's not deprecated there:

/*! This creates the record in the default zone. */
- (instancetype)initWithRecordType:(CKRecordType)recordType;

- (instancetype)initWithRecordType:(CKRecordType)recordType recordID:(CKRecordID *)recordID;
- (instancetype)initWithRecordType:(CKRecordType)recordType zoneID:(CKRecordZoneID *)zoneID;

@property (nonatomic, readonly, copy) CKRecordType recordType;
@property (nonatomic, readonly, copy) CKRecordID *recordID;


2) ignore the documents and warning in Swift

Hi,


I know this is a bit old now but I had the same problem and I've found the solution by trying to implement the deprecated initializer and following the swift sugestion under the warning:


So the solution is:


let recordID = CKRecord.ID(zoneID: myCustomZoneID)
let newRecord = CKRecord(recordType: "Item", recordID: recordID)


My previous mistake was to think that was not possible to use the CKRecord.ID initializer without specifing the "recordName:" like it suggest in the autocomplete.


Hope this helps other people in future.

CKModifyRecordsOperation can take multiple records, and without recordIDs they wouldn't be able to be individually identified.


Any reason why you're reluctant to create your own recordID?


let recordID = CKRecordID(recordName: UUID().uuidString, zoneID: myZoneID)

Here is the code to save a record in a custom zone.


func addRecordToCustomZone() {       
    let ckRecordZoneID = CKRecordZone(zoneName: "CustomZoneName")
    let ckRecordID = CKRecord.ID(zoneID: ckRecordZoneID.zoneID)
    let aRecord = CKRecord(recordType: "Cars", recordID: ckRecordID)// Cars is the data Type

    aRecord["carMake"] = "Porche" // carMake is a field in the Cars Type.
    aRecord["carModel"] = "Carrera" // carModel is a field in the Cars Type.
    privateDatabase.save(aRecord, completionHandler: { (record, error) -> Void in
        if let error = error {
            print(error)
        }
        else {
            print("record saved successfully")
        }
    })
}


Please note that you also have the option of adding your own record name if you like by specifying it in the `CKRecord.ID` as follow.


let ckRecordID = CKRecord.ID(recordName: "SomeUniqueName", zoneID: ckRecordZoneID.zoneID)