Instagram API从WebView获取响应NSURL请求

时间:2016-09-13 10:17:58

标签: ios swift api instagram

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

enter image description here

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!

}

1 个答案:

答案 0 :(得分:0)

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

使用前

别忘了填写

let redirectURI = ""
let clientID = ""
let clientSecret = ""
NetworkManager.swift文件中的

代码

  

User.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

enter image description here