我正在Swift 3中开发一个iOS照片共享扩展程序,用于捕获iOS照片应用中用户选择的照片以及用户输入的标题,并将其存储在Firebase中。照片存储在Firebase存储中。 Firebase存储中的标题和照片路径存储在Firebase实时数据库中。
我遇到的问题是首次发送后共享扩展程序停止工作。奇怪的是,如果我在iOS应用程序中的常规View Controller中执行类似的方法,则代码可以正常工作。我注意到共享扩展有两个问题:
问题#1:共享扩展视图未被完全解雇。在正常情况下,视图将返回到"画廊"照片模式。但是,共享扩展视图正在消失,但共享菜单中包含您可以用来共享的完整应用列表并不会被忽略。
Screenshot of what the Photos view looks like after the second send
问题#2:数据未发送到Firebase存储或Firebase数据库。
下面请找我的ShareViewController代码:
import UIKit
import Social
import Firebase
import MobileCoreServices
class ShareViewController: SLComposeServiceViewController {
var ref: DatabaseReference!
var storageRef: StorageReference!
override func isContentValid() -> Bool {
// Do validation of contentText and/or NSExtensionContext attachments here
return true
}
override func didSelectPost() {
// This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments.
FirebaseApp.configure()
ref = Database.database().reference()
storageRef = Storage.storage().reference()
// Inform the host that we're done, so it un-blocks its UI. Note: Alternatively you could call super's -didSelectPost, which will similarly complete the extension context.
if let item = self.extensionContext?.inputItems[0] as? NSExtensionItem {
for ele in item.attachments!{
let itemProvider = ele as! NSItemProvider
if itemProvider.hasItemConformingToTypeIdentifier("public.jpeg"){
itemProvider.loadItem(forTypeIdentifier: "public.jpeg", options: nil, completionHandler: { (item, error) in
do {
var imgData: Data!
if let url = item as? URL{
imgData = try Data(contentsOf: url)
}
if let img = item as? UIImage{
imgData = UIImagePNGRepresentation(img)
}
var updateRef = self.ref.child("demo_group").child("demo_patient").child("demo_updates").childByAutoId()
var updateStorageRef = self.storageRef.child("demo_photos" + "/\(Double(Date.timeIntervalSinceReferenceDate * 1000)).jpg")
updateRef.child("event_name").setValue(self.contentText)
updateRef.child("sender").setValue("demo_ff")
let metadata = StorageMetadata()
metadata.contentType = "image/jpeg"
updateStorageRef.putData(imgData, metadata: metadata) { (metadata, error) in
if let error = error {
print("Error uploading: \(error)")
return
}
// use sendMessage to add imageURL to database
updateRef.child("photos").childByAutoId().setValue(metadata?.path)
}
} catch let err{
print(err)
}
})
}
}
}
self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
}
override func configurationItems() -> [Any]! {
// To add configuration options via table cells at the bottom of the sheet, return an array of SLComposeSheetConfigurationItem here.
return []
}
}
如果我有什么办法可以解决这个问题,请告诉我!我将不胜感激。
答案 0 :(得分:3)
如果连续多次调用,FirebaseApp.configure()会使您的扩展名崩溃,因为系统没有完全释放为扩展程序创建的firebase应用实例。
我的解决方案是:
if let _ = FirebaseApp.app() {...} else {
FirebaseApp.configure()
}
这可以解决您的问题。
编辑:另请注意,您应该在存储后调用extensionContext.complete。数据库更新已完成......不在
之前因此,您需要使用带有完成块的setValue方法。 1-任务完成时上传到存储 2-更新数据库引用, 3-当调用完成块时...然后调用extensionContext.completeWith()或.cancel()