是否应该处理 "behind" 警报?

Should processing be happening "behind" the alert?

我正在编写一个例程来检查文件是否存在,如果存在则提醒用户并询问我是否应该覆盖。我发现对我来说是奇怪的行为。

这是我编写文件的代码。

    if let jsonToSave = myFile.json {
            var shouldIOverwrite: Bool = false
          if let url = try? FileManager.default.url(
                for: .documentDirectory,
                in: .userDomainMask,
                appropriateFor: nil,
                create: true
                ).appendingPathComponent(name + ".json"){
                do {
                    print("place 1: \(shouldIOverwrite)")
                     shouldIOverwrite = presentOverwriteWarning(for: url, fName: name)
                    print("place 2: \(shouldIOverwrite)")
                    if shouldIOverwrite {   
                        try jsonToSave.write(to: url)
                        print("saved successfully")
                    }
                } catch let error {
                    print("couldn't save \(error)")
                }
            }
        }

这是设置和显示警报的函数:

private func presentOverwriteWarning(for url: URL?, fName: String) -> Bool {
    var overwrite: Bool = false

        let alert = UIAlertController(
            title: "File for \"" + fName + "\" exists",
            message: "Do you want to overwrite it?",
            preferredStyle: .alert
        )
        alert.addAction(UIAlertAction(
            title: "Yes",
            style: .default,
            handler: { action in
                 overwrite = true
        }
        ))
        alert.addAction(UIAlertAction(
            title: "No",
            style: .default,
            handler: { action in
                overwrite = false
        }
        ))
        present(alert, animated: true)

    return overwrite
}

我正在返回 Bool 值覆盖。请注意,我有两个打印命令 "place 1" 和 "place 2"。当我调试时,我看到的是,在我的警报在响应之前出现在我的屏幕上之前,这 2 个打印件已经在输出中列为 false。所以我的 "if overwrite " 总是错误的。我是不是遗漏了什么?

注意:您将看到没有代码来检查文件是否存在。为了调试,我总是调用警报。

我会更改您的 presentOverwriteWarning 函数以使用回调,而不是 return 任何东西,因为警报是异步的:

private func presentOverwriteWarning(for url: URL?, fName: String, callback: (Bool) -> Void) {
    let alert = UIAlertController(
        title: "File for \"" + fName + "\" exists",
        message: "Do you want to overwrite it?",
        preferredStyle: .alert
    )
    alert.addAction(UIAlertAction(
        title: "Yes",
        style: .default,
        handler: { action in
            callback(true)
    }
    ))
    alert.addAction(UIAlertAction(
        title: "No",
        style: .default,
        handler: { action in
            callback(false)
    }
    ))
    present(alert, animated: true)
}

然后您可以像这样使用它:

presentOverwriteWarning(for: url, fName: name) { overwrite in
    if (overwrite) {
         try jsonToSave.write(to: url)
    }
}

更新:要修复与 try jsonToSave 相关的编译错误,您需要移动 do-catch 块:

presentOverwriteWarning(for: url, fName: name) { overwrite in
    if (overwrite) {
         do {
            try jsonToSave.write(to: url)
         } catch {

         }
    }
}