【问题标题】:Instagram API get a response from WebView NSURL RequestInstagram API 从 WebView NSURL 请求中获得响应
【发布时间】:2017-01-20 21:50:25
【问题描述】:

我想从访问令牌中获取 .get 数据,但这似乎是不可能的,我尝试了几个小时来解决我的错误。我该如何解决?如何解决此错误并从 WebView NSURL 请求中获得响应?


import Foundation

class User {

    var id: String?
    var userName: String?
    var fullName: String?
    var profilePicture: String?
    var bio: String?
    var website: String?
    var mediaCount: String?
    var followsCount: Int?
    var followedByCount: Int?

    init(userDict:[String:AnyObject]) {


        self.id = userDict["id"] as? String
        self.userName = userDict["username"] as? String
        self.fullName = userDict["full_name"] as? String
        self.profilePicture = userDict["profile_picture"] as? String
        self.bio = userDict["bio"] as? String
        self.website = userDict["website"] as? String
        self.mediaCount = userDict["media"] as? String
        if let countsDict = userDict["counts"] as? [String: AnyObject] {
            self.followsCount = countsDict["follows"] as? Int
            self.followedByCount = countsDict["followed_by"] as? Int
        }
    }


    class func fetchUserInfo(withToken token: String, completionHandler: (User?, NSError?)->()) {
        var user: User?
        let url = NSURL(string: "https://api.instagram.com/v1/users/self/?access_token=\(token)")!
        NSURLSession().dataTaskWithURL(url) { (data, response, error) in
            guard error == nil else { return }

            do {
                if let jsonData = data,
                    let jsonDataDict = try NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.AllowFragments) as? [String: AnyObject],
                    let jsonUserDict = jsonDataDict["data"] as? [String: AnyObject] {
                    user = User(userDict: jsonUserDict)
                    dispatch_async(dispatch_get_main_queue(), {
                        completionHandler(user, error)
                    })
                }
            } catch let err as NSError {
                print(err.debugDescription)
            }

            }.resume()
    }

    var user = fetchUserInfo(withToken: "3923891960.a56f59d.7f2376b5acae4abf8f98eaf2a575adXX", completionHandler: updateUI)

    func updateUI(user: User?, error: NSError?) {

        avatarImage = user.profilePicture
        mediaLabel.text = user.mediaCount
        followsLabel.text = user.followsCount
        followedBy.text = user.followedByCount
        username.text = user.userName
        full_name.text = user.fullName
        bioLabel.text = user.bio
        websiteLabel.text = user.website


    }

}

//
//  TableViewCell.swift
//  CodeTaskInstagram
//
//

import UIKit

class TableViewCell: UITableViewCell {

    @IBOutlet var avatarImage: UIImageView!
    @IBOutlet var mediaLabel: UILabel!
    @IBOutlet var followsLabel: UILabel!
    @IBOutlet var followedBy: UILabel!
    @IBOutlet var username: UILabel!
    @IBOutlet var full_name: UILabel!
    @IBOutlet var bioLabel: UILabel!
    @IBOutlet var websiteLabel: UILabel!
    @IBOutlet var idLabel: UILabel!

    @IBOutlet var labelRecents: UILabel!

}

【问题讨论】:

    标签: ios swift api instagram


    【解决方案1】:

    在 swift 示例代码中获取 access_token 的 Instagram 授权:

    使用前

    别忘了填写

    let redirectURI = ""
    let clientID = ""
    let clientSecret = ""
    

    在 NetworkManager.swift 文件中

    代码

    用户.swift

    import Foundation
    
    class User {
    
    var id: String?
    var userName: String?
    var fullName: String?
    var profilePicture: String?
    var bio: String?
    var website: String?
    var followsCount: Int?
    var followedByCount: Int?
    
    init(userDict:[String:AnyObject]) {
    
        self.id = userDict["id"] as? String
        self.userName = userDict["username"] as? String
        self.fullName = userDict["full_name"] as? String
        self.profilePicture = userDict["profile_picture"] as? String
        self.bio = userDict["bio"] as? String
        self.website = userDict["website"] as? String
        if let countsDict = userDict["counts"] as? [String: AnyObject] {
            self.followsCount = countsDict["follows"] as? Int
            self.followedByCount = countsDict["followed_by"] as? Int
        }
    }
    
    var description: String {
        get {
            var result = ""
            result += descriptionString("id", value: id)
            result += descriptionString("userName", value: userName)
            result += descriptionString("fullName", value: fullName)
            result += descriptionString("profilePicture", value: profilePicture)
            result += descriptionString("bio", value: bio)
            result += descriptionString("website", value: website)
            result += descriptionInt("followsCount", value: followsCount)
            result += descriptionInt("followedByCount", value: followedByCount)
            return result
        }
    }
    
    private func descriptionString(name: String, value: String?) -> String{
        var result = "\(name): "
        if let _value = value {
            result += _value
        } else {
            result += "nil"
        }
        return result + "\n"
    }
    
    private func descriptionInt(name: String, value: Int?) -> String{
        var result = "\(name): "
        if let _value = value {
            result += "\(_value)"
        } else {
            result += "nil"
        }
        return result + "\n"
    }
    }
    

    NetworkManager.swift

    import Foundation
    
    class NetworkManager {
    
    var delegate: NetworkManagerDelegate?
    var accessToken: String? = nil
    var code: String? = nil
    
    let baseURLString = "https://api.instagram.com"
    let clientID = ""
    let redirectURI = "https://www.instagram.com/"
    let clientSecret = ""
    
    static let InstagramResponseError = "InstagramResponseError"
    }
    
    // MARK: Get/Set
    
    extension NetworkManager {
    
    var authentificationUrl: String {
        get {
            return "\(baseURLString)/oauth/authorize/?client_id=\(clientID)&redirect_uri=\(redirectURI)&response_type=code"
        }
    }
    
    class var sharedInstance: NetworkManager {
        struct Static {
            static var onceToken: dispatch_once_t = 0
            static var instance: NetworkManager? = nil
        }
        dispatch_once(&Static.onceToken) {
            Static.instance = NetworkManager()
        }
        return Static.instance!
    }
    }
    
    
    // MARK: Errors
    
    extension NetworkManager {
    
    func fetchError(jsonDataDict: [String: AnyObject]) -> NSError? {
    
        var error: NSError? = nil
    
        if let meta = jsonDataDict["meta"] as? [String:AnyObject] {
    
            if let code = meta["code"] as? Int {
    
                switch code {
    
                case 400:
                    error = NSError(domain: NetworkManager.InstagramResponseError, code: code, userInfo: meta)
    
                default:
                    break
                }
            }
        }
        return error
    }
    }
    
    // MARK: Load Data
    
    extension NetworkManager {
    
    func newRequest(url: String, HTTPMethod: String, paramString: String?, completionHandler: ([String: AnyObject]?, NSURLResponse?, NSError?) -> Void) {
    
        if let url =  NSURL(string:url) {
    
            let request = NSMutableURLRequest(URL: url)
            request.HTTPMethod = HTTPMethod
            if let paramString = paramString {
                request.HTTPBody = paramString.dataUsingEncoding(NSUTF8StringEncoding)!
            }
    
            let task =  NSURLSession.sharedSession().dataTaskWithRequest(request)  { (data, response, error) in
    
                do {
                    var json: [String: AnyObject]? = nil
                    var responseError: NSError? = error
    
                    if let jsonData = data {
                        if let jsonDataDict  = try NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.AllowFragments) as? [String: AnyObject] {
                            if let _responseError = self.fetchError(jsonDataDict) {
                                responseError = _responseError
                            }
    
                            json = jsonDataDict
                        }
                    }
    
                    completionHandler(json, response, responseError)
    
                } catch let err as NSError {
                    print(err.debugDescription)
                }
            }
    
            task.resume()
        }
    }
    
    func getAccessToken() {
    
        if let code = self.code {
    
            let urlString = "\(baseURLString)/oauth/access_token"
            let paramString  = "client_id=\(clientID)&client_secret=\(clientSecret)&grant_type=authorization_code&redirect_uri=\(redirectURI)&code=\(code)&scope=basic+public_content"
    
            newRequest(urlString, HTTPMethod: "POST", paramString: paramString) { (json, response, error) in
    
                if let json = json {
                    if let access_token = json["access_token"] as? String {
                        self.accessToken = access_token
                        NSLog("access_token: \(access_token)")
                    } else {
                        self.accessToken = nil
                    }
                }
                if let delegate = self.delegate {
                    delegate.getAccessTokenDidEnd(self.accessToken, error: error)
                }
            }
        }
    
    }
    
    func loadProfile() {
    
        if let accessToken = self.accessToken {
    
            let urlString = "https://api.instagram.com/v1/users/self/?access_token=\(accessToken)"
    
            newRequest(urlString, HTTPMethod: "GET", paramString: nil) { (json, response, error) in
    
                var user: User? = nil
    
                if let json = json {
                    if let userData = json["data"] as? [String:AnyObject] {
                        user = User(userDict: userData)
                    }
                }
    
                if let delegate = self.delegate {
                    delegate.loadProfileDidEnd(user, error: error)
                }
            }
        }
    }
    }
    

    NetworkManagerDelegate.swift

    import Foundation
    
    protocol NetworkManagerDelegate {
    func getAccessTokenDidEnd(accessToken: String?, error: NSError?)
    func loadProfileDidEnd(user: User?, error: NSError?)
    }
    

    ProfileTableViewCell.swift

    import UIKit
    
    class ProfileTableViewCell: UITableViewCell {
    
    @IBOutlet var idLabel: UILabel!
    @IBOutlet var userNameLabel: UILabel!
    @IBOutlet var fullNameLabel: UILabel!
    @IBOutlet var profilePictureLabel: UILabel!
    @IBOutlet var bioLabel: UILabel!
    @IBOutlet var websiteLabel: UILabel!
    @IBOutlet var followsCountLabel: UILabel!
    @IBOutlet var followedByCountLabel: UILabel!
    
    func setData(user: User) {
    
        setLabel(idLabel, value: user.id)
        setLabel(userNameLabel, value: user.userName)
        setLabel(fullNameLabel, value: user.fullName)
        setLabel(profilePictureLabel, value: user.profilePicture)
        setLabel(bioLabel, value: user.bio)
        setLabel(websiteLabel, value: user.website)
        setLabel(followsCountLabel, value: user.followsCount)
        setLabel(followedByCountLabel, value: user.followedByCount)
    }
    
    private func setLabel(label: UILabel, value: String?) {
        if let _value = value {
            label.text = _value
        } else {
            label.text = "-"
        }
    }
    
    private func setLabel(label: UILabel, value: Int?) {
        if let _value = value {
            label.text = "\(_value)"
        } else {
            label.text = "-"
        }
    }
    }
    

    ViewController.swift

    import UIKit
    
    class ViewController: UIViewController {
    
    private var webView: UIWebView!
    @IBOutlet var tableView: UITableView!
    let instagramManager = NetworkManager.sharedInstance
    var user: User? = nil
    
    override func viewDidLoad() {
        super.viewDidLoad()
        instagramManager.delegate = self
        //log out
        // deleteChache()
        initWebView()
        initTableView()
    }
    
    private func actionWhenUserLogedIn() {
        self.webView.hidden = true
    }
    
    func deleteChache() {
        NSURLCache.sharedURLCache().removeAllCachedResponses()
        if let cookies = NSHTTPCookieStorage.sharedHTTPCookieStorage().cookies {
            for cookie in cookies {
                NSHTTPCookieStorage.sharedHTTPCookieStorage().deleteCookie(cookie)
            }
        }
    }
    }
    
    // MARK: NetworkManagerDelegate
    
    extension ViewController: NetworkManagerDelegate {
    
    func initNetworkManager() {
        instagramManager.delegate = self
    }
    
    func getAccessTokenDidEnd(accessToken: String?, error: NSError?) {
        instagramManager.loadProfile()
    }
    
    func loadProfileDidEnd(user: User?, error: NSError?) {
    
        self.user = user
    
        dispatch_async(dispatch_get_main_queue()) {
            self.tableView.hidden = false
            self.tableView.reloadData()
        }
    }
    }
    
    // MARK: UIWebView
    
    extension ViewController: UIWebViewDelegate {
    
    private func initWebView() {
    
        webView = UIWebView(frame: CGRect(x: 0, y: 0, width: UIScreen.mainScreen().bounds.width, height: UIScreen.mainScreen().bounds.height))
        webView.delegate = self
        view.addSubview(webView)
    
        authorizationRequestInWebView()
    }
    
    private func authorizationRequestInWebView() {
    
        if let url = NSURL(string: instagramManager.authentificationUrl) {
            let request = NSURLRequest(URL: url, cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 10.0)
            webView.loadRequest(request)
        }
    }
    
    func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    
        let urlString = (request.URL?.absoluteString)!
    
    
        if let range = urlString.rangeOfString(instagramManager.redirectURI + "?code=") {
    
            let location = range.endIndex
            let code = urlString.substringFromIndex(location)
            instagramManager.code = code
            NSLog("code: \(code)")
            instagramManager.getAccessToken()
    
            actionWhenUserLogedIn()
            return false
        }
    
        return true
    }
    }
    
    // MARK: UITableView
    
    extension ViewController: UITableViewDataSource, UITableViewDelegate {
    
    func initTableView() {
        tableView.delegate = self
        tableView.dataSource = self
        tableView.hidden = true
    }
    
    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }
    
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }
    
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    
        let cell = tableView.dequeueReusableCellWithIdentifier("ProfileTableViewCell")!
    
        if let profileTableViewCell = cell as? ProfileTableViewCell {
            if let user = self.user {
                profileTableViewCell.setData(user)
            }
        }
    
        return cell
    }  
    }
    

    Main.storyboard

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-29
      • 2020-05-06
      • 1970-01-01
      • 2017-06-22
      相关资源
      最近更新 更多