我正在為具有云功能的 macOS 開發一個筆記應用程式專案,特別是下載另一個人的筆記,給出筆記“CloudID”,這只是當筆記上傳到云時云資料庫給出的記錄的唯一名稱。我使用 sqlite 資料庫進行本地資料存盤,使用 cloudKit 資料庫進行公共資料存盤。當我測驗下載功能時,它會將資料正確地添加到 sqlite DB,但是我附加到我的 notesArray 的本地物件,該物件用于在我的主頁中填充 NSTableView 沒有被修改。
這是代碼:
@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()
}
我假設這是一個范圍問題,我嘗試移動 append func,我嘗試將原始下載的note宣告設定為一個未像這樣初始化的可選型別:var downloadedNote: Note?然后在 fetch func 中對其進行初始化,例如所以:downloadedNote = Note(id: notesArray.count, title: noteRecord["Title"] as! String, body: noteRecord["Body"] as! String)沒有一個作業正常。我讓它最接近作業的是現在的代碼。請讓我知道我哪里出錯以及如何解決它。非常感謝您的幫助!
uj5u.com熱心網友回復:
CloudKit異步作業。移動代碼以通知并將表重新加載到閉包中
代替
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()
和
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聞起來很客觀,而且已經過時了。使用FileManagerURL 相關 API
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)
...
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/449850.html
