首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从CKRecord创建本地对象并将其附加到NSTableView数据的数组中

如何从CKRecord创建本地对象并将其附加到NSTableView数据的数组中
EN

Stack Overflow用户
提问于 2022-03-16 15:29:00
回答 1查看 46关注 0票数 0

我正在为macOS开发一个带有云功能的便笺应用程序项目,特别是下载另一个人的便笺"CloudID“,这正是云数据库在将便条上传到云时给记录的唯一名称。我使用sqlite数据库进行本地数据存储,cloudKit数据库用于公共数据存储。当我测试下载特性时,它将数据正确地添加到sqlite中,但是我附加到我的notesArray (用于在主页中填充NSTableView )的本地对象没有被修改。

下面是代码:

代码语言:javascript
复制
@IBAction func downloadNoteFromCloud(_ sender: Any) {
    // 1.) check to make sure text field isn't empty
    if (noteIDTextField.stringValue == "") {
        noteIDTextField.stringValue = "Please enter the desired note's cloudID"
    }
    
    // 2.) query the note with the given cloudID
    
    // make note object for the downloaded note bc of scope issues
    var downloadedNote = Note(0, "", "")
    
    //sets cloudDB to the public cloud database
    let container = CKContainer.default()
    let cloudDB = container.publicCloudDatabase
    
    let noteRecordID = CKRecord.ID(recordName: noteIDTextField.stringValue)
    
    // returns a CKRecord
    cloudDB.fetch(withRecordID: noteRecordID) { record, error in
        if let error = error {
            // Handle error
            print(error)
            return
        }
        // Record fetched successfully
        if let noteRecord = record {
            // set the values of the downloadedNote obj equal the the values of the noteRecord
            downloadedNote.setValues((notesArray.count), noteRecord["Title"] as! String, noteRecord["Body"] as! String)
            
            // add to local database ~ this works
            do {
                let path = NSSearchPathForDirectoriesInDomains(
                    .applicationSupportDirectory, .userDomainMask, true
                ).first! + "/" + Bundle.main.bundleIdentifier!

                // create parent directory iff it doesn’t exist
                try FileManager.default.createDirectory(
                atPath: path, withIntermediateDirectories: true, attributes: nil
                )
                
                //connect to DB
                let db = try Connection("\(path)/db.sqlite3")
                //Define the Notes Table and its Columns
                let notes = Table("Notes")
                //ID is primary key so it doesn't need to be defined for inserts
                let title = Expression<String>("Title")
                let body = Expression<String>("Body")
                
                try db.run(notes.insert(title <- downloadedNote.title, body <- downloadedNote.body))
            }
            catch {
                print(error)
            }
        }
    }
    // append downloadedNote to notesArray
    notesArray.append(downloadedNote)
    
    //Send Notification to reload the tableView data
    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "load"), object: nil)
    
    //Return to home page
    self.view.window?.close()
}

我假设这是一个范围问题,我尝试移动追加功能,并尝试将原始的downloadedNote声明设置为一个可选类型,而不是像这样初始化:var downloadedNote: Note?,然后在fetch中初始化它,比如:downloadedNote = Note(id: notesArray.count, title: noteRecord["Title"] as! String, body: noteRecord["Body"] as! String):没有一个正确工作。我让它最接近的是代码现在是如何工作的。请让我知道我哪里出了问题,以及如何解决。非常感谢您的帮助!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-16 15:36:21

CloudKit异步工作。移动代码通知并将表重新加载到闭包中。

替换

代码语言:javascript
复制
           try db.run(notes.insert(title <- downloadedNote.title, body <- downloadedNote.body))
        }
        catch {
            print(error)
        }
    }
}
// append downloadedNote to notesArray
notesArray.append(downloadedNote)

//Send Notification to reload the tableView data
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "load"), object: nil)

//Return to home page
self.view.window?.close()

使用

代码语言:javascript
复制
           try db.run(notes.insert(title <- downloadedNote.title, body <- downloadedNote.body))

           DispatchQueue.main.async {
               // append downloadedNote to notesArray
               notesArray.append(downloadedNote)

               //Send Notification to reload the tableView data
               NotificationCenter.default.post(name: NSNotification.Name(rawValue: "load"), object: nil)

               //Return to home page
               self.view.window?.close()
           }
        }
        catch {
            print(error)
        }
    }
}

并在闭包中创建新的注释。不再存在范围问题,

附带说明:

NSSearchPathForDirectoriesInDomains闻起来很客观,而且过时了.使用FileManager URL相关的API

代码语言:javascript
复制
do {
    let fm = FileManager.default
    let applicationSupportURL = try fm.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
    let applicationSupportBundleURL = applicationSupportURL.appendingPathComponent(Bundle.main.bundleIdentifier!)
    
    if !fm.fileExists(atPath: applicationSupportBundleURL.path) {
        // create parent directory iff it doesn’t exist
        try fm.createDirectory(at: applicationSupportBundleURL, withIntermediateDirectories: true, attributes: nil)
    }
    let dbPath = applicationSupportBundleURL.appendingPathComponent("db.sqlite3").path
    
    //connect to DB
    let db = try Connection(dbPath)
    ...
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71499858

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档