从iOS 11共享时,iOS共享扩展名崩溃 [英] iOS Share Extension crashes when sharing from iOS 11 Screenshot

查看:90
本文介绍了从iOS 11共享时,iOS共享扩展名崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用使用照片共享扩展程序的iOS应用程序,该应用程序中会处理图像并触发我们的主要功能.

I'm working on an iOS app that uses a photo share extension, where the image is processed and our main function is triggered.

在Photo的应用程序中的模拟器中,这很好用.我决定从Photo的应用程序在设备上运行,并且效果也很好,但是当我截屏并尝试从iOS 11的新快速截屏"共享时,扩展崩溃了,有什么主意吗?

In the simulator on the Photo's app, this works great. I decided to run on the device from the Photo's app and it also works great, but when I screenshot and try to share from iOS 11's new "Quick screenshot" the extension crashes, any ideas?

扩展名获取图像,将其发送到服务器,获取响应并显示该响应(全部在扩展名中).从快速的屏幕截图访问Messenger和Snapchat共享扩展程序后,它们仍然可以正常工作!

The extension takes an image, sends it to the server, gets a response and displays that response (all in the extension). This annoys me as Messenger and Snapchat share extensions still work when accessed from a quick screenshot!!

Xcode 9也没有提供共享扩展名中的任何日志.还值得注意的是,我使用的开发人员帐户在每次在设备上重新安装应用程序时都需要信任".

Xcode 9 also isn't giving me any logs from the share extension. it's also worth noting that I'm using a developer account that I need to "trust" each time I reinstall the app on the device.

代码:

// App Group keys

let suiteName = "group.suite.id"

override func viewDidLoad() {
    print("Styling views..")
    styleViews()
    print("Styled views")
    print("Adding notifications..")
    addNotifications()
    print("Added notifications")
    print("Fetching image..")
    fetchSharedImage()
}

func styleViews(){
    // Set up main view
    mainView.layer.cornerRadius = 8
    mainShadowView.addShadow()

    // Set up views and buttons
    // Code hidden, applies shadows etc.

    // Code hidden, moves constraints of a view
}

func addNotifications(){
    // Helps views tell their parent (this view controller) to navigate to another form
    NotificationCenter.default.addObserver(forName: NotificationDisplayFetchedLink, object: nil, queue: nil){ notification in
        // Handles user info in lambda block
        guard let userInfo = notification.userInfo,
            let link = userInfo["link"] as? String
            else {
                print("No userInfo found in notification")
                return
            }
        self.displayResult(with: link)
    }
}

func fetchSharedImage(){
    // Make sure we have a valid extension item
    if let content = extensionContext!.inputItems[0] as? NSExtensionItem {
        let contentType = kUTTypeImage as String

        // Verify the provider is valid
        if let contents = content.attachments as? [NSItemProvider] {
            // look for images
            for attachment in contents {
                if attachment.hasItemConformingToTypeIdentifier(contentType) {
                    attachment.loadItem(forTypeIdentifier: contentType, options: nil) { data, error in
                        let url = data as! URL
                        if let imageData = try? Data(contentsOf: url) {
                            self.selectedImage = UIImage(data: imageData)

                            DispatchQueue.main.async {
                                self.selectedImageView.layer.cornerRadius = 8
                                self.selectedImageView.image = self.selectedImage
                            }
                            self.makeWebRequest()

                        }
                    }
                }
            }
        }
    }
}

func makeWebRequest(){
    let url = URL(string: "url.json")
    let task = URLSession.shared.dataTask(with: url!) { data, response, error in
        guard error == nil else {
            return
        }
        guard let data = data else {
            // Data is empty
            return
        }

        let json = try! JSONSerialization.jsonObject(with: data, options: []) as! NSDictionary
        guard let dict = json as? [String:Any] else { return }
        let item = dict["item"]
        guard let itemData = item as? [[String:Any]] else { return }
        let link = itemData[0]["url"]
        NotificationCenter.default.post(name: NotificationDisplayFetchedLink, object: nil, userInfo: [link: link!])
    }
    task.resume()
}

因此,解决方案(如Owen Zhao所说)是iOS 11屏幕截图编辑器返回UIImage,而像照片"之类的应用程序将返回URL.

So the solution (as Owen Zhao has said) is that the iOS 11 screenshot editor returns a UIImage, while apps like Photos would return URL.

我优雅地处理此问题的方法是将UIImage或转换为UIImage的URL保存到iOS临时目录(三天后删除),然后将该目录中图像的URL返回到共享扩展名.

My solution to handling this elegantly was saving the UIImage OR the URL cast to a UIImage to the iOS temporary directory (deleted after 3 days) and then returning the URL of the image in that directory to the share extension.

推荐答案

let url = data as! URL if let imageData = try? Data(contentsOf: url) {

let url = data as! URL if let imageData = try? Data(contentsOf: url) {

问题是因为此处的数据不是URL.这是一个"public.image",请尝试转换为UIImage而不是Data.

The issue is because the data here is not a URL. It is a "public.image", try to convert to UIImage instead of Data.

这篇关于从iOS 11共享时,iOS共享扩展名崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆