如何远程将数据加载到Cloudkit

时间:2017-09-22 09:19:05

标签: ios swift cloudkit

我已经构建了一个利用Apple的Cloudkit功能的应用程序。我觉得困难的是新的笨拙的Couldkit UI。这使得加载大量数据甚至修改现有记录变得困难。是否可以通过其他方法将数据加载到Cloudkit中?例如,有没有办法将CSV文件加载到Cloudkit中?

1 个答案:

答案 0 :(得分:1)

我为我的一个应用程序播放(并更新)一个CloudKit容器,其中包含来自FileMaker数据库的记录。我的数据源是.tab文件而不是.csv,但它的工作原理相同。对于我的项目,我有一个Artist类。

首先,将.csv文件添加到Xcode项目中。

然后,您需要将其分解为带有data.components(separatedBy: "\r")的返回分隔的行数组。

该数组中的每一行都需要用data.components(separatedBy: ",")拆分。我的源文件通常包含逗号,所以我喜欢使用标签("\t")来区分它们。

// [Artist]
func makeArtistArray(_ fileName: String) -> [Artist] {

    var array = [Artist]()

    do {
        let path = Bundle.main.path(forResource: fileName, ofType: nil)
        let data = try String(contentsOfFile: path!, encoding: String.Encoding.utf8)
        let rows = data.components(separatedBy: "\r")

        // rows.removeAtIndex(0) // if first row contains field names

        for row in rows {

            let values = row.components(separatedBy: "\t")

            let artist = Artist()

            artist.auctionGroup     = values[0] as CKRecordValue
            artist.auctionNumber    = Int(values[1])
            artist.auctionOrder     = Int(values[2])...

            array.append(artist)
        }

    } catch {
        print(error)
    }

    return array
}

然后,我将该数组传递给一个创建[CKRecord]数组的函数,并将所有内容保存到我的容器的公共数据库中。如果您提前知道CKRecordID,则可以使用它来修改现有记录。如果您传递不存在的CKRecordID(或完全省略它),您将创建一个新记录:

// [CKRecord]
func makeCloudRecords(_ array: [Artist], recordType: String) {

    var records = [CKRecord]()

    for artist in array {

        let recordID  = CKRecordID(recordName: "\(artist.name!) - Artist")            
        let record    = CKRecord(recordType: recordType, recordID: recordID)

        record["auctionGroup"]   = artist.auctionGroup
        record["auctionNumber"]  = artist.auctionNumber as NSNumber?
        record["auctionOrder"]   = artist.auctionOrder as NSNumber?...

        records.append(record)
    }

    // operation
    let operation = CKModifyRecordsOperation(recordsToSave: records, recordIDsToDelete: nil)
    operation.savePolicy = .allKeys

    operation.modifyRecordsCompletionBlock = { savedRecords, deletedRecordIDs, operationError in

        if let error = operationError {
            // error
        }

        if let saved = savedRecords {
            // print artist.name, or count the array, or whatever..                
        }
    }

    database.add(operation)
}

然后,最后,在您的应用中设置一个调用makeArtistArray()的按钮,并将结果传递给makeCloudRecords()

学习如何做到这一点(当时)进行了大量的试验和错误,没有官方文档。但是我已经成功使用这些功能一年多了,定期使用2个生产应用程序。希望这能让你朝着正确的方向前进。

*提醒..对components(separatedBy:)的调用会产生一个字符串数组,因此请注意转换非字符串值,否则容器的记录架构将不满意。