iOS分享扩展显示我的应用程序,但在点击后不会打开它。

huangapple go评论76阅读模式
英文:

iOS Share extension shows my app but does not open it after clicking on it

问题

我已经为您翻译了所提供的代码和文本部分。请查看以下翻译结果:

import UIKit
import Social
import CoreServices
import UniformTypeIdentifiers

class ShareViewController: UIViewController {

    private let typeText = UTType.text.identifier
    private let typeURL = UTType.url.identifier
    private let appURL = "MyExtension://"

    private let groupName = "group.sharingsampletwo"
    private let urlDefaultName = "incomingURL"

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        // 1
        guard let extensionItem = extensionContext?.inputItems.first as? NSExtensionItem,
            let itemProvider = extensionItem.attachments?.first else {
                self.extensionContext?.completeRequest(returningItems: nil, completionHandler: nil)
                return
        }

        if itemProvider.hasItemConformingToTypeIdentifier(typeText) {
            handleIncomingText(itemProvider: itemProvider)
        } else if itemProvider.hasItemConformingToTypeIdentifier(typeURL) {
            handleIncomingURL(itemProvider: itemProvider)
        } else {
            print("Error: No url or text found")
            self.extensionContext?.completeRequest(returningItems: nil, completionHandler: nil)
        }
    }

    // ... (其余代码未翻译)
}

// AppDelegate 代码也未翻译

关于您的问题,是否需要付费的苹果开发者账户取决于您要使用的功能。在您的代码中,您似乎在共享扩展中使用了App Groups,这意味着您的主应用程序和共享扩展可以共享数据。通常,如果您要在App Groups 中共享数据,您需要使用付费的苹果开发者账户。

您还需要确保您的应用程序的 App ID 配置正确,并且您的应用程序包含了正确的 App Groups Entitlement。此外,请确保您的应用程序的 Bundle Identifier 和 App Groups 的标识符匹配。

除了上述内容,您还需要确保所有其他应用程序配置(如 URL Scheme)正确设置,以便与共享扩展进行通信。确保在您的主应用程序和共享扩展之间进行正确的配置和数据传输是至关重要的。

请注意,我的知识截止日期是2021年9月,有关苹果开发者账户和应用程序配置的详细信息可能会在之后发生变化。因此,建议查阅最新的苹果开发者文档以获取最新的信息和要求。

英文:

I have added share extension to my iOS app. Then I deleted the storyboard from share extension. My ShareViewController code is as follows

import UIKit
import Social
import CoreServices
import UniformTypeIdentifiers

class ShareViewController: UIViewController {

    private let typeText = UTType.text.identifier
    private let typeURL = UTType.url.identifier
    private let appURL = "MyExtension://"
    
    private let groupName = "group.sharingsampletwo"
    private let urlDefaultName = "incomingURL"

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        // 1
        guard let extensionItem = extensionContext?.inputItems.first as? NSExtensionItem,
            let itemProvider = extensionItem.attachments?.first else {
                self.extensionContext?.completeRequest(returningItems: nil, completionHandler: nil)
                return
        }

        if itemProvider.hasItemConformingToTypeIdentifier(typeText) {
            handleIncomingText(itemProvider: itemProvider)
        } else if itemProvider.hasItemConformingToTypeIdentifier(typeURL) {
            handleIncomingURL(itemProvider: itemProvider)
        } else {
            print("Error: No url or text found")
            self.extensionContext?.completeRequest(returningItems: nil, completionHandler: nil)
        }
    }

    private func handleIncomingText(itemProvider: NSItemProvider) {
        itemProvider.loadItem(forTypeIdentifier: typeText, options: nil) { (item, error) in
            if let error = error { print("Text-Error: \(error.localizedDescription)") }


            if let text = item as? String {
                do {// 2.1
                    let detector = try NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
                    let matches = detector.matches(
                        in: text,
                        options: [],
                        range: NSRange(location: 0, length: text.utf16.count)
                    )
                    // 2.2
                    if let firstMatch = matches.first, let range = Range(firstMatch.range, in: text) {
                        self.saveURLString(String(text[range]))
                    }
                } catch let error {
                    print("Do-Try Error: \(error.localizedDescription)")
                }
            }

            self.openMainApp()
        }
    }

    private func handleIncomingURL(itemProvider: NSItemProvider) {
        itemProvider.loadItem(forTypeIdentifier: typeURL, options: nil) { (item, error) in
            if let error = error { print("URL-Error: \(error.localizedDescription)") }

            if let url = item as? NSURL, let urlString = url.absoluteString {
                self.saveURLString(urlString)
            }

            self.openMainApp()
        }
    }

    private func saveURLString(_ urlString: String) {
        UserDefaults(suiteName: self.groupName)?.set(urlString, forKey: self.urlDefaultName)
    }

    private func openMainApp() {
        self.extensionContext?.completeRequest(returningItems: nil, completionHandler: { _ in
            guard let url = URL(string: self.appURL) else { return }
            _ = self.openURL(url)
        })
    }

    // Courtesy: https://stackoverflow.com/a/44499222/13363449 👇🏾
    // Function must be named exactly like this so a selector can be found by the compiler!
    // Anyway - it's another selector in another instance that would be "performed" instead.
    @objc private func openURL(_ url: URL) -> Bool {
        var responder: UIResponder? = self
        while responder != nil {
            if let application = responder as? UIApplication {
                return application.perform(#selector(openURL(_:)), with: url) != nil
            }
            responder = responder?.next
        }
        return false
    }
}

Then I added appgroups capability for my main app target as well as share extension

iOS分享扩展显示我的应用程序,但在点击后不会打开它。

Then I edited info.plist of my share extension

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    
	<key>NSExtension</key>
	<dict>
		<key>NSExtensionAttributes</key>
		<dict>
			<key>NSExtensionActivationRule</key>
            <dict>
                <key>NSExtensionActivationSupportsText</key>
                <true/>
                <key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
                <integer>1</integer>
            </dict>
		</dict>
		<key>NSExtensionPointIdentifier</key>
		<string>com.apple.share-services</string>
        <key>NSExtensionPrincipalClass</key>
        <string>Share.ShareViewController</string>
	</dict>
</dict>
</plist>

Then in my appdelegate I added following code

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
      if let scheme = url.scheme,
        scheme.caseInsensitiveCompare("MyExtension") == .orderedSame,
        let page = url.host {
        
        var parameters: [String: String] = [:]
        URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems?.forEach {
          parameters[$0.name] = $0.value
        }
        
        print("redirect(to: \(page), with: \(parameters))")
        for parameter in parameters where parameter.key.caseInsensitiveCompare("url") == .orderedSame {
          UserDefaults().set(parameter.value, forKey: "incomingURL")
        }
        
      }
      
      return true
      
    }

Do I need to have paid apple developer account for this? What else am I missing

答案1

得分: 1

你需要在项目文件中添加一个URL scheme。
项目 > 信息 > 滚动到 URL 类型 > 添加一个新的URL类型。

确保你创建的URL scheme与你在共享扩展中定义的相匹配(即,在你的情况下是 MyExtension://)。

查阅苹果文档中有关URL schemes的信息以获取更多信息。

英文:

You need to add a URL scheme in your project file.
Project > Info > Scroll down to URL Types > Add a new URL type.

Make sure the URL scheme you create match the one you define in your share extension (i.e. MyExtension:// in your case).

Refer the to Apple docs for URL schemes for more info.

huangapple
  • 本文由 发表于 2023年6月1日 19:47:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76381556.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定