Я использую Core Data для хранения данных моего пользователя.Я хочу предложить кнопку «Поделиться» в пользовательском интерфейсе для экспорта данных в любое место.Я сделал класс, соответствующий UIActivityItemSource
.Он успешен, когда просто возвращает объект данных из activityViewController:itemForActivityType
, но файл имеет системное имя файла.Поэтому сейчас я пытаюсь сгенерировать UIDocument
на лету, сохранить его в файловой системе и вернуть URL
(UIDocument.fileURL
) в контроллер представления активности.Проблема в UIDocument.save
асинхронная, но я не могу вернуться с activityViewController:itemForActivityType
, пока файл не будет сохранен.Мой последний код выглядит так:
Класс init:
let saveQueue = DispatchQueue(label: "saveQueue")
let saveSemaphore = DispatchSemaphore(value: 0)
...
func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
var success = false
self.saveQueue.async {
self.document.save(to: self.document.fileURL,
for: .forOverwriting) {(didSucceed) in
success = didSucceed
self.saveSemaphore.signal()
}
}
saveSemaphore.wait()
return success ? document.fileURL : nil
}
Поведение - асинхронный код запускается, но завершается сохранениефункция никогда не вызывается.Что я сделал (и не сделал)?
Мое окончательное решение, с помощью Кейси, было переопределить UIDocument.save
.
override func save(to url: URL, for saveOperation: UIDocument.SaveOperation, completionHandler: ((Bool) -> Void)? = nil) {
do {
let contents = try self.contents(forType: GlobalConst.exportType) as! Data
try contents.write(to: url, options: [.atomicWrite])
completionHandler?(true)
} catch {
print("write error: \(error)")
completionHandler?(false)
}
}
Мне еще предстоит понять, почему сохранение суперкласса было проблемой, но я могу позволитьэто скользит.