iT邦幫忙

2021 iThome 鐵人賽

DAY 21
0
Mobile Development

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

Day22 Plugin 從零開始到上架 - 取得權杖(iOS)

iOS這邊在取得授權碼後,一樣準備取得權杖

Modules:

struct ShortAccessTokenResponse: Decodable {
    var accessToken : String
    var userId : Int
}

struct LongAccessTokenResponse: Decodable {
    var accessToken : String
    var tokenType : String
    var expiresIn: Int64
}

AccessTokenRepository:

    
    func getShortAccessTokenInfo(clientId: String, clientSecret: String, code: String, redirectUri: String, completionHandler: @escaping (ShortAccessTokenResponse) -> Void) {
        
        let url = URL(string: "https://api.instagram.com/oauth/access_token")!
        
        
        let headers = [
            "content-type": "multipart/form-data; boundary=\(boundary)"
        ]
        let parameters = [
            [
                "name": "client_id",
                "value": clientId
            ],
            [
                "name": "client_secret",
                "value": clientSecret
            ],
            [
                "name": "grant_type",
                "value": "authorization_code"
            ],
            [
                "name": "redirect_uri",
                "value": redirectUri
            ],
            [
                "name": "code",
                "value": code
            ]
        ]
        
        var request = URLRequest(url: url)
        let postData = getFormBody(parameters, boundary)
        
        request.allHTTPHeaderFields = headers
        request.httpMethod = "POST"
        
        request.httpBody = postData
        
        URLSession.shared.dataTask(with: request) {
            data, response, error in
            if let data = data {
                let decoder = JSONDecoder()
                decoder.keyDecodingStrategy = .convertFromSnakeCase
                do {
                    let response = try decoder.decode(ShortAccessTokenResponse.self, from: data)
                    completionHandler(response)
                } catch {
                    print(error.localizedDescription)
                }
            } else {
                print("No Data")
            }
        }.resume()
    }
    
    func getLongAccessTokenInfo(accessToken: String,clientSecret: String,grantType: String, completionHandler: @escaping (LongAccessTokenResponse) -> Void) {
        
        let url = URL(string: "https://graph.instagram.com/access_token?access_token=\(accessToken)&client_secret=\(clientSecret)&grant_type=\(grantType)")!
        
        let request = URLRequest(url: url)
        
        URLSession.shared.dataTask(with: request) {
            data, response, error in
            if let data = data {
                do {
                    let decoder = JSONDecoder()
                    decoder.keyDecodingStrategy = .convertFromSnakeCase
                    
                    let response = try decoder.decode(LongAccessTokenResponse.self, from: data)
                    
                    completionHandler(response)
                    
                }catch(let error) {
                    print(error.localizedDescription)
                }
            } else {
                print("No Data")
            }
        }.resume()
    }
    
    func logout() {
        instagramUser = nil
    }

AccessTokenViewModel:

    enum State {
        case isLoading
        case failed(Error)
        case loaded(UserInfoResponse)
    }
    
    @Published private(set) var state :State? = nil
    
    func getAccessToken(clientId: String, clientSecret: String, code: String, redirectUri: String) {
        state = State.isLoading
        
        AccessTokenRepository.shared.getShortAccessTokenInfo(clientId: clientId, clientSecret: clientSecret, code: code, redirectUri: redirectUri) { response in
            DispatchQueue.main.async {
                AccessTokenRepository.shared.getLongAccessTokenInfo(accessToken: response.accessToken, clientSecret: clientSecret, grantType: "ig_exchange_token") { longAccessTokenResponse in
                    
                    AccessTokenRepository.shared.saveInstagramInfo(userId: clientId, accessToken: longAccessTokenResponse.accessToken, expiresIn: longAccessTokenResponse.expiresIn)
                    
                    do {
                        try AccessTokenRepository.shared.getUserInfo { response in
                            self.state = State.loaded(response)
                        }
                    }catch(let error) {
                        print(error.localizedDescription)
                        self.state = State.failed(error)
                    }

                }
            }
        }
    }

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

尚未有邦友留言

立即登入留言