Swift3 为什么这个简单的iCloud存储应用程序失败了?

Swift3 为什么这个简单的iCloud存储应用程序失败了?,swift3,icloud,xcode8.2,ios10.2,Swift3,Icloud,Xcode8.2,Ios10.2,这是我第一次制作iCloud应用程序,我正在关注(以及如何设置iCloud应用程序)。它所做的只是接受文本(通过“文本视图”对象),并将文本(通过UIButton)保存到存储在iCloud中的文档中。我已经到了教程的末尾,当我测试它时,它崩溃了。好吧,我不应该说“崩溃”,因为当我测试其他应用程序时,Xcode会结束测试,这里不是这样。应用程序一直在运行,但我什么都做不了(我不能写任何文本或用“保存”按钮保存) 这是ViewController.swift的代码 import UIKit cla

这是我第一次制作iCloud应用程序,我正在关注(以及如何设置iCloud应用程序)。它所做的只是接受文本(通过“文本视图”对象),并将文本(通过UIButton)保存到存储在iCloud中的文档中。我已经到了教程的末尾,当我测试它时,它崩溃了。好吧,我不应该说“崩溃”,因为当我测试其他应用程序时,Xcode会结束测试,这里不是这样。应用程序一直在运行,但我什么都做不了(我不能写任何文本或用“保存”按钮保存)

这是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.
    }


}
以下是应用程序“崩溃”时的输出:

下面是一些潜在问题的截图:

Xcode想让我去掉“let resultur”,所以我这样做了(如下所示),希望这能解决问题,但它没有


我在这里真的是太深了,所以我只是简单地遵循一个教程。我真的很感谢你的帮助。如果需要添加更多信息,请告诉我。我不知道问题出在哪里,所以我可能遗漏了一些重要的信息

断点所在的行读取第一个结果(索引0),而不检查是否有任何结果(在后续行中检查)

我猜您没有收到任何查询结果。您可以查看准备时设置的条件,还可以查看iCloud上是否确实存在您期望的数据。

删除此行:

let resultURL = query.value(ofAttribute: NSMetadataItemURLKey,
                                forResultAt: 0) as! URL

谢谢你的帮助!你能添加一些示例代码吗?我如何检查是否有任何结果?检查后续行是错误的做法吗?我没有写这段代码,而是一个教程,所以我不能100%确定到底发生了什么。如何查看条件,以及如何在iCloud上查看是否有数据?if query.resultCount>0将告诉您是否有任何结果。您可以将该行设置为有条件的if条件,或者(正如travis所建议的)完全删除它,因为您似乎不需要它。
let resultURL = query.value(ofAttribute: NSMetadataItemURLKey,
                                forResultAt: 0) as! URL