2016-10-27 2 views
6

На IG есть много изменений. Многие репозитории OAuth2, похоже, имеют ошибки или действительно не легко конвертируются в Swift3. Хотите узнать, есть ли у кого-нибудь решение перейти на Swift3 и работать с последними изменениями в Instagram?OAuth2, Swift 3, Instagram

Решения наиболее приветствуются. Реализация OAuth2 представляется одной из самых сложных вещей. Удивлен, что IG не предложил свои собственные примеры документов о том, как это сделать с iOS. У них есть только документы для веб-решений.

Возможно, что-то там заваривается? Циллионы кодеров, которые у них есть у сотрудников. Но пока, на охоте за (смею я говорю?) Простое решение.

спасибо миллион. :-)

+0

я использую oauth2 в Swift 3 войти в Facebook. Я думаю, что это похоже ... если хочешь ... Я мог бы написать для тебя. –

+0

Да, FB классный, но отличается от Instagram. Instagram - сложная задача, которую мне нужно решить. URL-адрес обратного вызова - это головоломка. –

ответ

12

Для Swift 3:

обновление: 17 апреля 2017: Из-за сломанные зависимости, установка на стручках больше не работают. Поэтому я разорвал необходимый контент и создал new Github project с использованием заголовка моста и сохранил все необходимые файлы в проекте. Если вы клонируете или загрузите проект github, вы сразу сможете войти в Instagram.

Чтобы использовать эти файлы в вашем проекте, просто перетащите все файлы из папки SimpleAuth для вашего проекта, убедитесь, чтобы отметить copy item if needed

enter image description here

Кроме того, необходимо отключить Disable implicit oAuth в Instagram консоль разработчика.

enter image description here

Тогда вы либо копировать/вставить свой код из Bridging заголовка в ваш или использовать мою. Установите заголовок моста в настройках сборки цели.

enter image description here

Все остальное работает как и раньше:

У меня есть-структуру для Instagram счета:

struct InstagramUser { 

    var token: String = "" 
    var uid: String = "" 
    var bio: String = "" 
    var followed_by: String = "" 
    var follows: String = "" 
    var media: String = "" 
    var username: String = "" 
    var image: String = "" 
} 

Функция получить маркер:

typealias JSONDictionary = [String:Any] 
var user: InstagramUser? 
let INSTAGRAM_CLIENT_ID = "16ee14XXXXXXXXXXXXXXXXXXXXXXXXX" 
let INSTAGRAM_REDIRECT_URI = "http://www.davidseek.com/just_a_made_up_dummy_url" //just important, that it matches your developer account uri at Instagram 

extension ViewController { 

    func connectInstagram() { 

     let auth: NSMutableDictionary = ["client_id": INSTAGRAM_CLIENT_ID, 
             SimpleAuthRedirectURIKey: INSTAGRAM_REDIRECT_URI] 

     SimpleAuth.configuration()["instagram"] = auth    
     SimpleAuth.authorize("instagram", options: [:]) { (result: Any?, error: Error?) -> Void in 

      if let result = result as? JSONDictionary { 

       var token = "" 
       var uid = "" 
       var bio = "" 
       var followed_by = "" 
       var follows = "" 
       var media = "" 
       var username = "" 
       var image = "" 

       token = (result["credentials"] as! JSONDictionary)["token"] as! String 
       uid = result["uid"] as! String 

       if let extra = result["extra"] as? JSONDictionary, 
        let rawInfo = extra ["raw_info"] as? JSONDictionary, 
        let data = rawInfo["data"] as? JSONDictionary { 

        bio = data["bio"] as! String 

        if let counts = data["counts"] as? JSONDictionary { 
         followed_by = String(describing: counts["followed_by"]!) 
         follows = String(describing: counts["follows"]!) 
         media = String(describing: counts["media"]!) 
        } 
       } 

       if let userInfo = result["user_info"] as? JSONDictionary { 
        username = userInfo["username"] as! String 
        image = userInfo["image"] as! String 
       } 

       self.user = InstagramUser(token: token, uid: uid, bio: bio, followed_by: followed_by, follows: follows, media: media, username: username, image: image) 


      } else { 
       // this handles if user aborts or the API has a problem like server issue 
       let alert = UIAlertController(title: "Error!", message: nil, preferredStyle: UIAlertControllerStyle.alert) 
       alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil)) 
       self.present(alert, animated: true, completion: nil) 
      } 

      if error != nil { 
       print("Error during SimpleAuth.authorize: \(error)") 
      } 
     } 
    } 
} 

Instagram также говорит:

Важно

Даже если наши маркеры доступа не указывать время истечения срока действия, ваше приложение должно обрабатывать случай, либо пользователь запрещает доступ, или Instagram истекает маркер после некоторого периода времени.Если токен недействителен, ответы API будут содержать "error_type = OAuthAccessTokenException". В этом случае вам необходимо будет повторно аутентифицировать пользователя для получения нового действительного токена. Другими словами: не предполагают, что ваш access_token действителен навсегда.

Так обрабатывать случай получения OAuthAccessTokenException

+0

привет, Дэвид, спасибо за информацию. Я действительно ищу версию Swift3. SimpleAuth не компилируется с последним кодом xcode. –

+1

чувак. Я использую его с последним xcode в быстром 3 проекте. если бы я не хотел, я бы не потратил 30 минут своей жизни, чтобы написать этот ответ –

+0

все, что вам нужно сделать, это скомпилировать зависимости simpleauth к swift 3 ... загрузить образец проекта за секунду для вас. –

0

Этот код ниже я использую для facebook и google +, я думаю, что это тоже будет работать для Instagram, возможно, некоторые настройки.

import UIKit 

class Signup: UIViewController, UIWebViewDelegate { 
    let GOOGLE_ID = "xxxxxx.apps.googleusercontent.com" 
    let GOOGLE_SECRET = "xxxxxxx"; 
    let GOOGLE_REDIRECT_URI="http://yourdomain.com/api/account/googlecallback" 
    let GOOGLE_TOKEN_URL = "https://accounts.google.com/o/oauth2/token"; 
    let GOOGLE_OAUTH_URL = "https://accounts.google.com/o/oauth2/auth"; 
    let GOOGLE_OAUTH_SCOPE = "profile email"; 
    let GOOGLE_GET_PROFILE = "https://www.googleapis.com/userinfo/v2/me"; 
    let FACEBOOK_ID = "xxxxx"; 
    let FACEBOOK_REDIRECT_URI = "http://yourdomain.com/api/account/facebookcallback"; 
    let FACEBOOK_OAUTH_URL = "https://www.facebook.com/dialog/oauth?client_id="; 
    let FACEBOOK_OAUTH_SCOPE = "public_profile,email" 
    let FACEBOOK_GET_PROFILE = "https://graph.facebook.com/me?access_token=" 
    var currentURL: String = "" 
    var queryString: String = "" 
    var receivedToken: String = "" 
    var authCode: String = "" 
    var authComplete = false 
    var webV:UIWebView = UIWebView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)) 
    @IBAction func google(_ sender: AnyObject) { 
     AppVars.Provider = "Google" 
     webV.delegate = self 
     let url = GOOGLE_OAUTH_URL + "?redirect_uri=" + GOOGLE_REDIRECT_URI + "&response_type=code&client_id=" + GOOGLE_ID + "&scope=" + GOOGLE_OAUTH_SCOPE 
     let urlString :String = url.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)! 
     webV.loadRequest(URLRequest(url: URL(string:urlString)!)) 
     self.view.addSubview(webV) 
    } 

    @IBAction func facebook(_ sender: AnyObject) { 
     AppVars.Provider = "Facebook" 
     webV.delegate = self 
     let url = FACEBOOK_OAUTH_URL + FACEBOOK_ID + "&redirect_uri=" + FACEBOOK_REDIRECT_URI + "&scope=" + FACEBOOK_OAUTH_SCOPE + "&display=popup&response_type=token" 
     let urlString :String = url.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)! 
     webV.loadRequest(URLRequest(url: URL(string:urlString)!)) 
     self.view.addSubview(webV) 
    } 
    func webView(_ webView: UIWebView, didFailLoadWithError error: Error) { 
     self.showAlert(self, message: "Internet is not working") 
    } 

    func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool { 
     return true; 
    } 

    func webViewDidStartLoad(_ webView: UIWebView) { 
    } 

    func webViewDidFinishLoad(_ webView: UIWebView) { 
     currentURL = (webView.request?.url!.absoluteString)! 
     if AppVars.Provider == "Google" { 
      googleSignup((webView.request?.url!)!) 
     } else { 
      facebookSignup((webView.request?.url!)!) 
     } 
    } 

    func googleSignup (_ returnCode: URL) { 
      let url = String(currentURL) 
      if (url?.range(of: "?code=") != nil && authComplete != true) { 
       authCode = getQueryItemValueForKey("code", url: returnCode)! 
       authComplete = true 
       let paramString = "code=" + authCode + "&client_id=" + GOOGLE_ID + "&client_secret=" + 
        GOOGLE_SECRET + "&redirect_uri=" + GOOGLE_REDIRECT_URI + "&grant_type=authorization_code" 
       self.requestServer(urlSource: GOOGLE_TOKEN_URL, params: paramString, requestType: "POST") { (dataResult, errorResult) ->() in 
        if errorResult != nil { 
         self.showAlert(self, message: "Internet is not working") 
        } else { 
         let dataString:NSString = NSString(data: dataResult as! Data, encoding: String.Encoding.utf8.rawValue)! 
         let dataResult2 = dataString.data(using: String.Encoding.utf8.rawValue, allowLossyConversion: false)! 
         do { 
          let jsonDict = try JSONSerialization.jsonObject(with: dataResult2, options: .allowFragments) as! [String:Any] 
          if let token = jsonDict["access_token"] as? String { 
           self.requestServerSignup(self.GOOGLE_GET_PROFILE, param: token, requestType: "GET") { (dataResult, errorResult) ->() in 
            if errorResult != nil { 
             self.showAlert(self, message: "Internet is not working") 
            } else { 
             let dataString:NSString = NSString(data: dataResult as! Data, encoding: String.Encoding.utf8.rawValue)! 
             let dataResult2 = dataString.data(using: String.Encoding.utf8.rawValue, allowLossyConversion: false)! 
             do { 
              let jsonDict = try JSONSerialization.jsonObject(with: dataResult2, options: .allowFragments) as! [String:Any] 
              if let name = jsonDict["name"] as? String { 
               AppVars.NameLogin = name 
               AppVars.PictureLogin = jsonDict["picture"] as! String 
               AppVars.EmailLogin = jsonDict["email"] as! String 
               self.performSegue(withIdentifier: "externalLoginSegue", sender: self) 
               // show picture, email and name for checking profile 
              } 
             } catch { 
              self.showAlert(self, message: "Internet is not working") 
             } 
            } 
           } 
          } 

         } catch { 
          self.showAlert(self, message: "Internet is not working") 
         } 
        } 
       } 
       self.webV.removeFromSuperview() 
      } 

    } 

    func facebookSignup(_ returnCode: URL) { 
      let url = String(currentURL) 
      if (url?.range(of: "access_token=") != nil && authComplete != true) { 
       let url2: String = returnCode.absoluteString.replacingOccurrences(of: "#access_token", with: "access_token") 
       let url3: URL = URL(string: url2)! 
       authCode = getQueryItemValueForKey("access_token", url: (url3))! 
       authComplete = true 
       let paramString = "code=" + authCode + "&client_id=" + GOOGLE_ID + "&client_secret=" + 
        GOOGLE_SECRET + "&redirect_uri=" + GOOGLE_REDIRECT_URI + "&grant_type=authorization_code" 
       self.requestServer(urlSource: self.FACEBOOK_GET_PROFILE + authCode + "&fields=name,picture,email", params: paramString, requestType: "GET") { (dataResult, errorResult) ->() in 
        if errorResult != nil { 
         self.showAlert(self, message: "Internet is not working") 
        } else { 
         let dataString:NSString = NSString(data: dataResult as! Data, encoding: String.Encoding.utf8.rawValue)! 
         let dataResult2 = dataString.data(using: String.Encoding.utf8.rawValue, allowLossyConversion: false)! 
         do { 
          let jsonDict = try JSONSerialization.jsonObject(with: dataResult2, options: .allowFragments) as! [String:Any] 
          if let name = jsonDict["name"] as? String { 
           AppVars.NameLogin = name 
           if let picture = jsonDict["picture"] as? [String:Any] { 
            if let dataPicture = picture["data"] as? [String:Any] { 
             if let url = dataPicture["url"] as? String { 
              AppVars.PictureLogin = url 
             } 
            } 
           } 
           AppVars.EmailLogin = jsonDict["email"] as! String 
           self.performSegue(withIdentifier: "externalLoginSegue", sender: self) 
           // show picture, email and name for checking profile 
          } 

         } catch { 
          self.showAlert(self, message: "Internet is not working") 
         } 
        } 
       } 
       self.webV.removeFromSuperview() 
      } 

    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 
    } 


    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 


    func getQueryItemValueForKey(_ key: String, url: URL) -> String? { 
     guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false) else { 
      return nil 
     } 
     guard let queryItems = components.queryItems else { return nil } 
     return queryItems.filter { 
      $0.name == key 
      }.first?.value 
    } 

    func requestServer(urlSource:String, params:String, requestType:String, result:@escaping (_ dataResult:NSData?, _ errorResult:NSError?) ->()) { 
     let url: URL = URL(string: urlSource)! 
     var request = URLRequest(url:url) 
     request.httpMethod = requestType 
     request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type") 
     if params.characters.count > 0 { 
      request.httpBody = params.data(using: String.Encoding.utf8) 
     } 
     let session = URLSession.shared 
     session.dataTask(with: request) { (data, response, error) -> Void in 
      DispatchQueue.main.async(execute: {() -> Void in 
       if error == nil { 
        result(data as NSData?, nil) 
       } else { 
        result(nil, error as NSError?) 
       } 
      }) 
     }.resume() 
    } 

} 
+0

привет умный, спасибо за информацию. IG немного отличается от Google или FB. Смешной тип возвращаемого значения, а токены с кодом возвращают значения. Также необходимо иметь решение Swift3. –

Смежные вопросы