iT邦幫忙

2021 iThome 鐵人賽

DAY 20
0
Mobile Development

Flutter - 從 Packages & Plugins 掌握原生系列 第 20

Day20 Plugin 從零開始到上架 - 取得授權碼(iOS)

接下來我們先切到iOS,換去處理iOS是如何取得權杖的

目標

與Androi 步驟一樣,須先取得INSTAGRAM_CLIENT_ID、INSTAGRAM_CLIENT_SECRET 和 REDIRECT_URI 後,透過這些資料打開WebView,來取得短期權杖最後所需要的授權碼code

iOS端

先建立一個AccessTokenViewController來取得權杖,同樣須先把之前取得資訊傳入,打開WebView後依照流程及能取得授權碼,之後再透過AccessTokenViewModel用這些資料取得權杖(下一篇內容)

class AccessTokenViewController: UIViewController, WKUIDelegate, WKNavigationDelegate{
    
    var webView: WKWebView!
    var delegate: DismissBackDelegate?
    
    var clientId: String?
    var clientSecret: String?
    var redirectUri: String?
    
    private let viewModel = AccessTokenViewModel()
    private var cancellable: AnyCancellable? = nil
    var loadSpinner: UIActivityIndicatorView!
    
    override func loadView() {
        let webConfiguration = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.navigationDelegate = self
        webView.uiDelegate = self
        view = webView
    }
    override func viewDidLoad() {
        super.viewDidLoad()

        clientId = Bundle.main.object(forInfoDictionaryKey: "INSTAGRAM_CLIENT_ID") as? String
        clientSecret = Bundle.main.object(forInfoDictionaryKey: "INSTAGRAM_CLIENT_SECRET") as? String
        redirectUri = Bundle.main.object(forInfoDictionaryKey: "REDIRECT_URI") as? String
        
        if clientId != nil && redirectUri != nil {
            let urlString = "https://www.instagram.com/oauth/authorize?client_id=\(clientId!)&redirect_uri=\(redirectUri!)&scope=user_profile,user_media&response_type=code"

            let myURL = URL(string:urlString)
            let myRequest = URLRequest(url: myURL!)
            webView.load(myRequest)
        }else{
            print("Need to set Secrets.xcconfig first.")
        }
        
        cancellable = viewModel.$state.sink { [weak self] state in
            self?.render(state)
        }
        
        loadSpinner = UIActivityIndicatorView(style: UIActivityIndicatorView.Style.medium)
        loadSpinner.color = .gray
        webView.addSubview(loadSpinner)
        
        view = webView
        
    }
    
    override func viewDidLayoutSubviews() {
        loadSpinner.center = webView.center
    }
    
    private func render(_ state: AccessTokenViewModel.State?) {
        switch state {
        case .isLoading:
            print("isLoading")
            loadSpinner.startAnimating()
        case .failed(let error):
            print("failed \(error)")
        case .loaded(let response):
            userInfoResponse = response
            DispatchQueue.main.async {
                self.dismiss(animated: true, completion: nil)
            }
        case .none:
            print("none")
        }
    }
    
    deinit {
        delegate?.dismissBack(userInfoResponse: userInfoResponse)
    }
    
    func webView(
        _ webView: WKWebView,
        decidePolicyFor navigationAction: WKNavigationAction,
        decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        
        if let frame = navigationAction.targetFrame,
           !frame.isMainFrame {
            decisionHandler(.cancel)
            return
        }
        
        guard let url = navigationAction.request.url else {
            decisionHandler(.allow)
            return
        }
        
        if url.absoluteString.starts(with: "\(redirectUri!)?code=") {
            decisionHandler(.cancel)
            let requestURLString = url.absoluteString

            print("Response uri:", requestURLString)
            if let range = requestURLString.range(of: "\(redirectUri!)?code=") {
                let code = String(requestURLString[range.upperBound...].dropLast(2))
                viewModel.getAccessToken(clientId: clientId!, clientSecret: clientSecret!, code: code, redirectUri: redirectUri!)
            }
        }
        else {
            decisionHandler(.allow)
        }
    }
}

上一篇
Day19 Plugin 從零開始到上架 - 取得授權碼(Android)
下一篇
Day21 Plugin 從零開始到上架 - 取得權杖(Android)
系列文
Flutter - 從 Packages & Plugins 掌握原生30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言