gpt4 book ai didi

ios - 在多次调用 loadFileRepresentation 完成后运行 block

转载 作者:行者123 更新时间:2023-11-29 05:46:21 25 4
gpt4 key购买 nike

我正在使用 NSItemProvider 方法 loadFileRepresentation(forTypeIdentifier:completionHandler:)。此方法异步将一些数据写入临时文件,并立即返回表示此写入进度的 Progress 对象。它还接受一个 block ,当临时文件已写入并可供您使用时将调用该 block 。 (如果准备文件时出错,也会调用该 block 。)

我将连续多次调用此方法,并希望在我的 UI 中显示“请等待”消息,直到每个 block 完成。我怎样才能以线程安全的方式做到这一点?

最佳答案

显示一个带有“请稍候”消息的对话框。然后迭代扩展上下文的 inputItems 两次:一次只是为了计算我们要处理的文件数量,然后再次实际处理它们。当处理的文件数量等于我们预期的数量时,我们调用另一个实例方法来隐藏对话框并将控制权返回给主机应用程序。

为了线程安全,处理数量的递增以及处理数量与预期数量之间的比较是在串行DispatchQueue上完成的。这确保了即使传递给 loadFileRepresentation 的 block 的多个副本同时运行,扩展程序仍然能够正确识别何时完成文件处理。

import UIKit

class ShareViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)

guard let items = extensionContext?.inputItems as? [NSExtensionItem] else {
return
}

// Display a "please wait" message while we copy the files.

let alertVC = UIAlertController(title: nil,
message: "Processing files…",
preferredStyle: .alert)
present(alertVC, animated: false, completion: nil)

// Iterate through the files once, incrementing "numberExpected" each
// time we see a file we're interested in.

var numberExpected: Int = 0

for item in items {
guard let attachments = item.attachments else {
continue
}

for attachment in attachments {
if attachmentShouldBeProcessed(attachment) {
numberExpected += 1
}
}
}

// Iterate through the files again, actually processing them this time.
// After each file is done--whether it succeeded or not--we increment
// "numberProcessed" and compare it to "numberExpected". (It's very
// important that this be done in a thread-safe way, which we accomplish
// here by doing the comparison within a block that is run on a serial
// DispatchQueue.) If they're equal, call the finish() method to close
// the progress dialog and return control of the UI to the host app.

var numberProcessed: Int = 0
let queue = DispatchQueue(label: "com.myapp.file-processing-queue")

for item in items {
guard let attachments = item.attachments else {
continue
}

for attachment in attachments {
guard attachmentShouldBeProcessed(attachment) else {
continue
}
attachment.loadFileRepresentation(forTypeIdentifier: "public.png") { url, error in

// ...your business logic here...

queue.sync {
numberProcessed += 1
if numberProcessed == numberExpected {
DispatchQueue.main.async { [weak self] in
self?.finish()
}
}
}
}
}
}
}

func finish() {
// Dismiss the "processing items" dialog.
dismiss(animated: false, completion: nil)

// Inform the host app that we're done so it can un-block its UI.
extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
}

func attachmentShouldBeProcessed(_ attachment: NSItemProvider) -> Bool {
// ...your business logic here...
return true
}
}

关于ios - 在多次调用 loadFileRepresentation 完成后运行 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56121418/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com