Swift 3照片共享扩展与Firebase数据库首次发送后不工作

时间:2017-09-05 14:22:19

标签: ios swift cocoa-touch firebase firebase-realtime-database

我正在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 []
    }

}

如果我有什么办法可以解决这个问题,请告诉我!我将不胜感激。

1 个答案:

答案 0 :(得分:3)

如果连续多次调用,FirebaseApp.configure()会使您的扩展名崩溃,因为系统没有完全释放为扩展程序创建的firebase应用实例。

我的解决方案是:

if let _ = FirebaseApp.app() {...} else {
     FirebaseApp.configure()
}

这可以解决您的问题。

编辑:另请注意,您应该在存储后调用extensionContext.complete。数据库更新已完成......不在

之前

因此,您需要使用带有完成块的setValue方法。 1-任务完成时上传到存储 2-更新数据库引用, 3-当调用完成块时...然后调用extensionContext.completeWith()或.cancel()