阅读背景:

如何远程将数据加载到Cloudkit中

来源:互联网 

I have built an app that take advantage of Apple's Cloudkit functionality. What I find difficult is the new clumsy Couldkit UI. It makes it difficult to load a large amount of data or even modify existing records. Is it possible to load data into Cloudkit via other methods? For example is there a way I could load a CSV file of records into Cloudkit?

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

1 个解决方案

#1


1  

I seed (and update) a CloudKit container for one of my apps with records from a FileMaker database. My data source is a .tab file rather than .csv, but it works the same. For my project, I have an Artist class.

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

First, add the .csv file to your Xcode project.

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

Then you need to break that into a return-delimited array of rows with data.components(separatedBy: "\r").

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

Each row in that array needs to be broken apart with data.components(separatedBy: ","). My source files often contain commas, so I like to break these apart using tab ("\t") instead.

该数组中的每一行都需要使用data.components(separatedBy:“,”)拆分。我的源文件通常包含逗号,所以我喜欢使用tab(“\ 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
}

Then, I pass that array to a function that creates a [CKRecord] array and saves everything to my container's public database. If you know your CKRecordID's ahead of time, you can use that to modify existing records. If you pass a non-existing CKRecordID (or omit it entirely), you'll create a new record:

然后,我将该数组传递给一个创建[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)
}

Then, finally, set a button in your app that calls makeArtistArray() and pass the result to makeCloudRecords().

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

Learning how to do this (at the time) took a lot of trial and error, with no official documentation. But I've been using these functions successfully over a year now, regularly, with 2 production apps. Hope this gets you going in the right direction.

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

*reminder.. the call to components(separatedBy:) results in an array of strings, so pay attention to casting non-string values, or your container's record schema won't be happy.

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


分享到: