美文网首页程序员iOS技术交流收藏iOS Developer
第四天--OAuth2.0授权和自定义的对象的归档和解档

第四天--OAuth2.0授权和自定义的对象的归档和解档

作者: 改变自己_now | 来源:发表于2016-08-26 00:10 被阅读343次

    前言:

    今天主要实现OAuth2.0登录和自定义的归档。用到的第三方和知识
    1、指示器 SVProgressHUD
    2、网络请求第三方Alamofire
    3、OAuth2.0微博开放平台
    4、自定义对象的归档和解档

    首先看下实现的简单效果

    2.gif
    1、OAuth2.0授权的机制如下图
    B227337D-6229-4AAC-86F8-36648494A562.png

    实现步骤
    1、加载授权页面(获取code)
    2、通过code后期accessToken
    3、通过accessToken去获取用户的信息

    采用webView来加载授权页面

    首先懒加载一个webView并遵守代理

    //MARK:懒加载
    lazy var webView:UIWebView = {
    
       
        let webView = UIWebView()
        
        
        
        webView.delegate = self
        
        return webView
    }()
    

    定义一些常量

       let ReBackURL:String = "https://api.weibo.com/oauth2/default.html" // 回调的URL
    
    let AppKey:String = "2100191772" // 程序appkey
    
    let AppSecret:String = "20701cb27e6279060eae21c1a7522f8c" // APPSecret
    

    注意:这里需要成为新浪的开放者,并且新建自己的应用,才有上面的信息。我就不在这里详细描述了。微博开放平台

    加载web view

       let urlString = "https://api.weibo.com/oauth2/authorize?client_id=\(AppKey)&redirect_uri=\(ReBackURL)";
        
        let url = NSURL(string: urlString)
        
        let request = NSURLRequest(URL: url!)
        
        webView.loadRequest(request)
    

    获取和获取accessToken主要下下面的代理方法中实现,拦截URL

    func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    
        
        let urlString:String = request.URL!.absoluteString
        
        if !urlString.hasPrefix(ReBackURL) {
            
            //如果不是回调Url就继续加载
            return true
        }
        
        // 判断是否授权成功
        let parameterStr = "code="
        if request.URL!.query!.hasPrefix(parameterStr) {
            
            //授权成功,取出code的参数用于
            print(request.URL!.query!)
        
            let code = request.URL!.query!.substringFromIndex(parameterStr.endIndex)
            
            // 获取accessToken
            
            requestAccessToken(code)
            
            
            
        }
        else {
        
            navigationController?.popViewControllerAnimated(true)
        }
        
        
        return false
    }
    

    获取accessToken的方法实现如下

    private func requestAccessToken(code:String){
    
        //
        let accessTokenPath = "https://api.weibo.com/oauth2/access_token"
        
        // 参数
        let params = ["client_id":AppKey,"client_secret":AppSecret,"grant_type":"authorization_code","code":code,"redirect_uri":ReBackURL]
        
        
        Alamofire.request(.POST, accessTokenPath, parameters: params, encoding: .URL, headers: nil).responseJSON { (response) in
            
            print(response.request)
            
            print(response.response)
            
            print(response.data)
            
            print(response.result)
            
            if let json = response.result.value {
            
                print("json\(json)")
                
                let userAccount = YJUserAccount(dict: json as![String:AnyObject])
                
                print(userAccount.access_token)
                userAccount.loginSuccess = true
                
                userAccount.savaAccount()
                
                //获取accessToken成功,证明登录成功了
                let base = YJBaseTabBarViewController()
                base.selectedIndex = 1
                
                UIApplication.sharedApplication().keyWindow?.rootViewController = base
                
                SVProgressHUD.showInfoWithStatus("登录成功")
                
            }
            
            
        }
    }
    

    通过上一步的code,去换取accessToken,请求成功后返回JSON数据,我们自定义一个Model去解析,并保存到本地。

    定义的模型YJUserAccount

    class YJUserAccount: NSObject,NSCoding
    

    要对自定义的对象实现归档和解档,需要遵守NSCoding协议并实现下面的两个方法

     //MARK:NSCoding
    func encodeWithCoder(aCoder: NSCoder) {
        
        /*  var access_token:String?  // 令牌
         var expires_in:NSNumber?  //  过期时间戳
         var uid: NSNumber? // 用户ID
         var loginSuccess:Bool = false // 是否登录成功*/
        
        aCoder.encodeObject(access_token, forKey: "access_token")
        aCoder.encodeObject(expires_in, forKey: "expires_in")
        aCoder.encodeObject(uid, forKey: "uid")
        aCoder.encodeBool(loginSuccess, forKey: "loginSuccess")
        
        
    }
    
    required init?(coder aDecoder: NSCoder) {
        
       access_token = aDecoder.decodeObjectForKey("access_token") as? String
       expires_in =  aDecoder.decodeObjectForKey("expires_in") as? NSNumber
       uid =  aDecoder.decodeObjectForKey("uid") as? NSNumber
       loginSuccess =  aDecoder.decodeBoolForKey("loginSuccess")
        
    }
    

    另外一注意一点就是字典转模型的,有些字没有,会出现崩溃的情况,可以改下下面的方法,就不会崩溃了。

    //为了不让其崩溃,重写该
    override func setValue(value: AnyObject?, forUndefinedKey key: String) {
        
    }
    

    归档和解档方法实现

    // 归档
    internal func savaAccount()   {
    
        let path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).last
        
        if let savePath = path {
        
            let archievePath = savePath.stringByAppendingString("/account.plist")
            
            print(archievePath)
            
           if  NSKeyedArchiver.archiveRootObject(self, toFile: archievePath)
           {
            
            print("归档成功")
            }
            
        }
        
        
      
    }
    
    // 解档
    internal class func loadAccount() -> YJUserAccount? {
        let path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).last
        
        
            
        let archievePath = path!.stringByAppendingString("/account.plist")
            
        let userAccoutn = NSKeyedUnarchiver.unarchiveObjectWithFile(archievePath) as? YJUserAccount
        return userAccoutn
        
        }
    

    上面就是简单的实现思路。

    相关文章

      网友评论

        本文标题:第四天--OAuth2.0授权和自定义的对象的归档和解档

        本文链接:https://www.haomeiwen.com/subject/ewiasttx.html