为什么这个简单的 iCloud 存储应用程序会失败?
Why is this simple iCloud storage app failing?
这是我第一次制作 iCloud 应用,我正在关注 this tutorial (and this supplemental tutorial 如何设置 iCloud 应用)。它所做的只是接受文本(通过 "Text View" 对象),并将该文本(通过 UIButton)保存到存储在 iCloud 中的文档中。我已经到了教程的结尾,当我测试它时,它崩溃了。好吧,我不应该说 "crash" 因为当我测试其他应用程序时, Xcode 结束测试,这里不是这样。该应用程序保持 运行,但我无法执行任何操作(我无法编写任何文本或使用 "save" 按钮保存)。
这是 ViewController.swift
的代码
import UIKit
class ViewController: UIViewController
{
@IBOutlet weak var textView: UITextView!
var document: MyDocument?
var documentURL: URL?
var ubiquityURL: URL?
var metaDataQuery: NSMetadataQuery?
func metadataQueryDidFinishGathering(notification: NSNotification) -> Void
{
let query: NSMetadataQuery = notification.object as! NSMetadataQuery
query.disableUpdates()
NotificationCenter.default.removeObserver(self,
name: NSNotification.Name.NSMetadataQueryDidFinishGathering,
object: query)
query.stop()
let resultURL = query.value(ofAttribute: NSMetadataItemURLKey,
forResultAt: 0) as! URL
if query.resultCount == 1 {
let resultURL = query.value(ofAttribute: NSMetadataItemURLKey,
forResultAt: 0) as! URL
document = MyDocument(fileURL: resultURL as URL)
document?.open(completionHandler: {(success: Bool) -> Void in
if success {
print("iCloud file open OK")
self.textView.text = self.document?.userText
self.ubiquityURL = resultURL as URL
} else {
print("iCloud file open failed")
}
})
} else {
document = MyDocument(fileURL: ubiquityURL!)
document?.save(to: ubiquityURL!,
for: .forCreating,
completionHandler: {(success: Bool) -> Void in
if success {
print("iCloud create OK")
} else {
print("iCloud create failed")
}
})
}
}
override func viewDidLoad()
{
super.viewDidLoad()
let filemgr = FileManager.default
ubiquityURL = filemgr.url(forUbiquityContainerIdentifier: nil)
guard ubiquityURL != nil else {
print("Unable to access iCloud Account")
print("Open the Settings app and enter your Apple ID into iCloud settings")
return
}
ubiquityURL = ubiquityURL?.appendingPathComponent(
"Documents/savefile.txt")
metaDataQuery = NSMetadataQuery()
metaDataQuery?.predicate =
NSPredicate(format: "%K like 'savefile.txt'",
NSMetadataItemFSNameKey)
metaDataQuery?.searchScopes =
[NSMetadataQueryUbiquitousDocumentsScope]
NotificationCenter.default.addObserver(self,
selector: #selector(
ViewController.metadataQueryDidFinishGathering),
name: NSNotification.Name.NSMetadataQueryDidFinishGathering,
object: metaDataQuery!)
metaDataQuery!.start()
}
@IBAction func saveDocument(_ sender: AnyObject)
{
document!.userText = textView.text
document?.save(to: ubiquityURL!,
for: .forOverwriting,
completionHandler: {(success: Bool) -> Void in
if success {
print("Save overwrite OK")
} else {
print("Save overwrite failed")
}
})
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
这是应用 "crashes":
时的输出
2017-03-15 15:12:06.531223 Gaethr2[2708:734758] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSMetadataQuery valueOfAttribute:forResultAtIndex:]: index (0) out of bounds (0)'
*** First throw call stack:
(0x1876951b8 0x1860cc55c 0x187695100 0x188125460 0x100102ffc 0x10010457c 0x18762eb10 0x18762e214 0x18762df90 0x18769db8c 0x18756fe64 0x1880a4e0c 0x188123268 0x18762eb10 0x18762e214 0x18762df90 0x18769db8c 0x18756fe64 0x1880a4e0c 0x19940d3e4 0x19940f29c 0x187642a44 0x187642240 0x187640094 0x18756e2b8 0x189022198 0x18d5b57fc 0x18d5b0534 0x100107720 0x1865515b8)
libc++abi.dylib: terminating with uncaught exception of type NSException
下面是潜在问题的一些屏幕截图:
Xcode 希望我摆脱 "let resultURL" 所以我做了(如下所示),希望能解决问题,但没有。
我在这里真的无法理解,因此我只是按照教程进行操作。我真的很感激一些帮助。让我知道是否需要添加更多信息。我不知道问题出在哪里,所以我可以省略一些重要信息。
设置断点的行读取第一个结果(索引 0)而不检查是否有任何结果(您在后续行检查)。
我猜您没有收到任何查询结果。你应该看看你在准备它时设置的条件,如果你期望的数据确实存在,也可以看看 iCloud。
删除这一行:
let resultURL = query.value(ofAttribute: NSMetadataItemURLKey,
forResultAt: 0) as! URL
这是我第一次制作 iCloud 应用,我正在关注 this tutorial (and this supplemental tutorial 如何设置 iCloud 应用)。它所做的只是接受文本(通过 "Text View" 对象),并将该文本(通过 UIButton)保存到存储在 iCloud 中的文档中。我已经到了教程的结尾,当我测试它时,它崩溃了。好吧,我不应该说 "crash" 因为当我测试其他应用程序时, Xcode 结束测试,这里不是这样。该应用程序保持 运行,但我无法执行任何操作(我无法编写任何文本或使用 "save" 按钮保存)。
这是 ViewController.swift
的代码import UIKit
class ViewController: UIViewController
{
@IBOutlet weak var textView: UITextView!
var document: MyDocument?
var documentURL: URL?
var ubiquityURL: URL?
var metaDataQuery: NSMetadataQuery?
func metadataQueryDidFinishGathering(notification: NSNotification) -> Void
{
let query: NSMetadataQuery = notification.object as! NSMetadataQuery
query.disableUpdates()
NotificationCenter.default.removeObserver(self,
name: NSNotification.Name.NSMetadataQueryDidFinishGathering,
object: query)
query.stop()
let resultURL = query.value(ofAttribute: NSMetadataItemURLKey,
forResultAt: 0) as! URL
if query.resultCount == 1 {
let resultURL = query.value(ofAttribute: NSMetadataItemURLKey,
forResultAt: 0) as! URL
document = MyDocument(fileURL: resultURL as URL)
document?.open(completionHandler: {(success: Bool) -> Void in
if success {
print("iCloud file open OK")
self.textView.text = self.document?.userText
self.ubiquityURL = resultURL as URL
} else {
print("iCloud file open failed")
}
})
} else {
document = MyDocument(fileURL: ubiquityURL!)
document?.save(to: ubiquityURL!,
for: .forCreating,
completionHandler: {(success: Bool) -> Void in
if success {
print("iCloud create OK")
} else {
print("iCloud create failed")
}
})
}
}
override func viewDidLoad()
{
super.viewDidLoad()
let filemgr = FileManager.default
ubiquityURL = filemgr.url(forUbiquityContainerIdentifier: nil)
guard ubiquityURL != nil else {
print("Unable to access iCloud Account")
print("Open the Settings app and enter your Apple ID into iCloud settings")
return
}
ubiquityURL = ubiquityURL?.appendingPathComponent(
"Documents/savefile.txt")
metaDataQuery = NSMetadataQuery()
metaDataQuery?.predicate =
NSPredicate(format: "%K like 'savefile.txt'",
NSMetadataItemFSNameKey)
metaDataQuery?.searchScopes =
[NSMetadataQueryUbiquitousDocumentsScope]
NotificationCenter.default.addObserver(self,
selector: #selector(
ViewController.metadataQueryDidFinishGathering),
name: NSNotification.Name.NSMetadataQueryDidFinishGathering,
object: metaDataQuery!)
metaDataQuery!.start()
}
@IBAction func saveDocument(_ sender: AnyObject)
{
document!.userText = textView.text
document?.save(to: ubiquityURL!,
for: .forOverwriting,
completionHandler: {(success: Bool) -> Void in
if success {
print("Save overwrite OK")
} else {
print("Save overwrite failed")
}
})
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
这是应用 "crashes":
时的输出2017-03-15 15:12:06.531223 Gaethr2[2708:734758] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSMetadataQuery valueOfAttribute:forResultAtIndex:]: index (0) out of bounds (0)'
*** First throw call stack:
(0x1876951b8 0x1860cc55c 0x187695100 0x188125460 0x100102ffc 0x10010457c 0x18762eb10 0x18762e214 0x18762df90 0x18769db8c 0x18756fe64 0x1880a4e0c 0x188123268 0x18762eb10 0x18762e214 0x18762df90 0x18769db8c 0x18756fe64 0x1880a4e0c 0x19940d3e4 0x19940f29c 0x187642a44 0x187642240 0x187640094 0x18756e2b8 0x189022198 0x18d5b57fc 0x18d5b0534 0x100107720 0x1865515b8)
libc++abi.dylib: terminating with uncaught exception of type NSException
下面是潜在问题的一些屏幕截图:
Xcode 希望我摆脱 "let resultURL" 所以我做了(如下所示),希望能解决问题,但没有。
我在这里真的无法理解,因此我只是按照教程进行操作。我真的很感激一些帮助。让我知道是否需要添加更多信息。我不知道问题出在哪里,所以我可以省略一些重要信息。
设置断点的行读取第一个结果(索引 0)而不检查是否有任何结果(您在后续行检查)。
我猜您没有收到任何查询结果。你应该看看你在准备它时设置的条件,如果你期望的数据确实存在,也可以看看 iCloud。
删除这一行:
let resultURL = query.value(ofAttribute: NSMetadataItemURLKey,
forResultAt: 0) as! URL