SwiftUI и UIKit взаимодействуют с требованиями UIViewController в старых API

Сценарий:

У меня есть простое представление SwiftUI, которое выглядит так:

struct AuthView: View {
    var body: some View {
        VStack {
            Button(action: handleLogin) {
                Text("Login to twitter")
            }
        }
    }

    private func handleLogin() {
        // do login stuff here
    }
}

Сейчас в идеале handleLogin Я бы просто выполнил запрос OAuth и обработал бы вход в систему и т. д. Однако я использую библиотеку, найденную на GitHub, для демонстрационных целей.

В этой библиотеке есть метод authorize(callBackUrl: URL, presentingController: UIViewController) который при вызове представляет контроллер Safari, который позволяет пользователю войти в Twitter. Однако позвонить authorize вам нужно передать в контроллер, который соответствует SFSafariViewControllerDelegate, Из моего нынешнего базового понимания является то, что View Тип из SwiftUI не является контроллером представления и, более того, не может соответствовать SFSafariViewControllerDelegate так как это структура.

Я посмотрел учебник Интерфейс с UIKit с сайта Apple, и они, кажется, создают UIViewControllerRepresentable введите, а затем из View типа вернуть этот "контроллер" в body из View, Это позволяет им использовать PageViewController из UIKit. Тем не менее, это не совсем тот случай использования, который мне нужен или нужен. Мне просто нужно уметь как-то преобразовать мою простую View в UIViewController, Было бы UIHostingController что нужно использовать здесь, и если да, то как будет внедрена эта зависимость, или представление должно даже знать / использовать контроллер?

По большей части мое замешательство заключается в том, что я еще не знаю, каковы лучшие практики SwiftUI. View Тип, кажется, заменить использование UIViewController в UIKit, но тогда как конвертация работает при взаимодействии с UIKit?

Если у кого-то есть идеи или вы хотели бы обсудить это, я буду признателен за это! Благодарю.

0 ответов

Я почти уверен, что есть лучший способ решить эту проблему, но вы можете получить вдохновение в следующем.

Просто чтобы дать вам некоторый контекст. Я создаю быстрый прототип для реализации авторизации Uber и добился этого следующим образом:

//
//  ContentView.swift
// 
//  Created by Daniel Tello on 05/11/19.
//  Copyright © 2019 Daniel Tello. All rights reserved.
//

import SwiftUI
import UberCore

struct ContentView: View {
    var body: some View {
        VStack {
            Button(action: uberLogin) {
            Text("Uber")
            }
        }
    }
}

func uberLogin() {
    let scopes: [UberScope] = [.profile, .places, .request]
    let presentingView = UIApplication.shared.windows.last?.rootViewController
    let loginManager = LoginManager(loginType: .native)

    loginManager.login(requestedScopes: scopes, presentingViewController: presentingView) { (accessToken, error) -> () in
        if accessToken != nil {
           NSLog("Got an AccessToken!")
        } else {
            // Error
            if let error = error {
                NSLog(error.localizedDescription)
            } else {
                NSLog("An Unknown Error Occured")
            }
        }
    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Другие вопросы по тегам