如何将数据从自定义 url 方案传递到 SwiftUI 中的视图?

Keo*_*oni 7 xcode ios swiftui

在 iOS 中处理自定义 URL 方案的技巧和教程不乏其人。ALL 未能做的实际上是向您展示如何将从这些 URL 解析的数据传递到您的应用程序/视图。是的,我可以使用全局变量,但这不是“正确”的方式,另外,如果您希望 Swift 视图对全局变量的更改做出反应,则不能。

例如,我有,

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>){
    let urlContext = URLContexts.first // Because I don't know how to properly deal with Sets
    if let url = urlContext?.url{
        guard let components = NSURLComponents(url: url, resolvingAgainstBaseURL: true),
            let params = components.queryItems else {
                print("Invalid URL or album path missing")
                return
        }
        if let token = params.first(where: { $0.name == "token" })?.value {
            print("Token: \(token)")
            MyGlobalToken = token
        }
    }        
}
Run Code Online (Sandbox Code Playgroud)

您会MyGlobalToken在其中看到有效的选项,但我无法响应该变量的更改。我是否必须对 做些什么,self.window?.rootViewController但我找不到任何关于该做什么的文档。或者您是否设置了“通知”以便您查看回复?或者这还没有在 SwiftUI 中实现?

FWIW 我是 iOS 开发的新手。

Ude*_*App 1

我在这个问题上遇到了很多麻烦。我对IOS的很多东西都不太了解。但没有答案。我写的。如果您不使用 sceneDelegate,您可以使用全局变量。(我不知道为什么它不起作用)

为此,我喜欢下面的内容。

  1. 删除 scenedelegate.swift。
  2. 删除 Info.plist 中的 sceneDelegate 东西
  3. 初始化检查变量

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
            // Override point for customization after application launch.
            UserDefaults.check = ""
            return true
        }
    
    Run Code Online (Sandbox Code Playgroud)
  4. 在 Appdelegate 中添加行以设置全局变量。

    open func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { 
        //set Global variable 
        // ... You should add check url for your application ...
        UserDefaults.check = "checked"
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
             if let uservc = self.storyboard?.instantiateViewController(withIdentifier: "MainViewController") as? MainViewController
             {
                 if #available(iOS 13.0, *) {
                    uservc.isModalInPresentation = true
                 }
                 uservc.debugText.text = "This is openUrl State"
                 self.present(uservc, animated: false) {
    
              }      
          }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  5. 制作 IntroViewController 和 MainViewController

    IntroViewController是根视图控制器。

    MainViewController 是第二个视图控制器。

    如果 check 变量被“选中”,则 IntroView 中的 Viewdidload 不会被执行。

    这次应用程序打开是用 safari 或 chrome 执行的。

    //IntroViewController
    class IntroViewController: UIViewController {
      override func viewDidLoad() {
      super.viewDidLoad()
      DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
        if UserDefaults.check.elementsEqual("") {
           if let uservc = 
              self.storyboard?.instantiateViewController(withIdentifier: "MainViewController") as? MainViewController
            {
                if #available(iOS 13.0, *) {
                    uservc.isModalInPresentation = true
                }
                uservc.debugText.text = "This is normal State"
                self.present(uservc, animated: false) {
                }
            }
        }
      }
    
    Run Code Online (Sandbox Code Playgroud)

6.全局变量

    //UserDefaults.swift
    import Foundation
    fileprivate let keyCheck = "keyCheck"

    extension UserDefaults {
       static var check: String {
         get {
            return UserDefaults.standard.string(forKey: keyCheck) ?? ""
         }
         set(value) {
            UserDefaults.standard.set(value, forKey: keyCheck)
            UserDefaults.standard.synchronize()
         }
      }
    }
Run Code Online (Sandbox Code Playgroud)

当我在 scenedelegate 中使用这个逻辑时,它工作得不好。(我无法检查“检查变量”。)