Почему происходит сбой этого простого приложения для хранения iCloud?
Я впервые делаю приложение для 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.
}
}
Вот вывод, когда приложение "падает":
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", поэтому я и сделал (как показано ниже), надеясь, что это решит проблему, но это не так.
Я действительно не в себе, поэтому я просто следую учебному пособию. Я был бы очень признателен за помощь. Дайте мне знать, если мне нужно добавить больше информации. Я не знаю, в чем проблема, поэтому я мог бы опустить важную информацию.
2 ответа
Удалить эту строку:
let resultURL = query.value(ofAttribute: NSMetadataItemURLKey,
forResultAt: 0) as! URL
Строка, в которой у вас есть точка останова, читает первый результат (индекс 0), не проверяя, были ли какие-либо результаты (которые вы проверяете в следующей строке).
Я предполагаю, что вы не получили никаких результатов по вашему запросу. Вы должны взглянуть на условия, которые вы установили при подготовке, а также посмотреть на iCloud, если ожидаемые данные действительно присутствуют.