4.新浪微博Swift项目第四天

第四天

今天我们主要练习使用OAuth授权相关, 我们可以在新浪的官方找到我们所需要的所有接口和返回数据格式,具体网址:新浪微博接口文档

今天我们关注的是access_token的作用,access_token,我们可以从新浪官方获取自己应用的access_token,获取方法如下:

  • 进入新浪官方的开发者网站,http://open.weibo.com
  • 点击文档
    输入图片说明
  • 接口测试工具
    输入图片说明
  • 左边就是我们这可以使用的access_token, 通过这个access_token我们可以进行各种网络请求,但是在实际开发中,这个access_token是由用户请求授权以后获得的
    输入图片说明
  • 另外AppkeyAppSecret 在以后的开发中也会用到,同样在我们的应用这里可以找到
    输入图片说明

下边我们就开始今天的任务!

1.首先使用cocoapods导入AFN,SDImage等第三方库

  • 具体的方法这里就不做介绍了,大家自行百度

###2.新建一个XQWBNetWorkManager.swift 封装网络请求类,管理网络请求

  • 1.首先我们创建一个网络请求的单例
     static let shared = XQWBNetWorkManager()
    
  • 2.声明一个access_token变量
var accessToken:String? = "xxxxxxxxxxxxxxxx" // 这个就是我们从接口测试工具中得到的access_token
  • 3.我们封装一个方法,包含POST和GET请求 具体代码如下:

    /// 封装 GET/POST 请求
    ///
    /// - Parameters:
    ///   - method: 请求方式
    ///   - URLString: url
    ///   - parameters: 参数
    ///   - completion: 回调
    func request(method:XQWBHTTPMethod = .GET, URLString: String,  parameters:[String:Any], completion:@escaping (_ json:Any?, _ isSuccess:Bool)->()) {
    
        // 成功回调
        let success = { (tast:URLSessionDataTask, json:Any?)->() in
            completion(json, true)
        }
        // 失败回调
        let failure = { (tast:URLSessionDataTask?, error:Error)->() in
            // 处理403
            if (tast?.response as? HTTPURLResponse)?.statusCode == 403 {
            //  print("token过期")
            //  发送通知,重新登录(谁接受谁处理)
                NotificationCenter.default.post(name: NSNotification.Name(rawValue: XQWBUserShouldLoginNotification), object: nil)
            }
            print("网络请求错误\(error)")
            completion(nil, false)
        }
    
        if method == .GET {
            get(URLString, parameters: parameters, progress: nil, success: success, failure: failure)
        }else {
            post(URLString, parameters: parameters, progress: nil, success: success, failure: failure)
        }
    }
    
    
  • 观察新浪的官方接口我们不难发现,几乎所有的接口都需要传入一个参数access_token,我们就可以将网络请求的方法再次封装,加入access_token

    // 负责拼接token
    func tokenRequest(method:XQWBHTTPMethod = .GET, URLString: String,  parameters:[String:Any]?, completion:@escaping (_ json:Any?, _ isSuccess:Bool)->())  {
    
        guard let token = accessToken else {
            // token 不存在
            // FIXME: 发送通知,重新登录(谁接受谁处理)
            completion(nil, false)
            return
        }
        // 判断参数字典是否存在
        var parameters = parameters
        if parameters == nil {
            parameters = [String:AnyObject]()
        }
        parameters!["access_token"] = token
        // 调用request  发起真正的请求
        request(method: method, URLString: URLString, parameters: parameters!, completion: completion)
    }
    
  • 另外声明一个枚举类型,实现请求的类型

    // 请求方式的枚举
    enum XQWBHTTPMethod {
        case GET
        case POST
    }    
    

3.新建一个XQWBNetWorkManager+Extension.swift 封装具体的网络请求

  • 封装一个专门负责请求微博首页数据的方法
    func statusList(completion:@escaping (_ list:[[String:Any]]?, _ isSuccess:Bool)->())  {
        // 加载微博数据
        let urlStr = "https://api.weibo.com/2/statuses/home_timeline.json"
    
        tokenRequest(URLString: urlStr, parameters: nil) { (json, isSuccess) in
            let tempJson = json as AnyObject
            let result = tempJson["statuses"] as? [[String:AnyObject]]
    
            completion(result, isSuccess)
        }
    }
    

4.新建一个微博数据的model

 // 目前我们只需要 id, text 2个属性做测试,等以后需要的时候在添加
   class XQWBStatus: NSObject {
       var id:Int64 = 0    // id
       var text:String?    // 内容
       // 重写description计算性属性
       override var description: String {
            return yy_modelDescription()
        }
   }  

5.建立 XQWBStatusListViewModel, 使用MVVM架构处理数据

    // 模型数组懒加载
    lazy var statusList = [XQWBStatus]()
    // 上拉次数限制
    fileprivate var pullupErrorTime = 0
    // 用来加载网络数据,以及回调
    func loadStatus(pullup:Bool, completion:@escaping (_ isSuccess:Bool, _ shouldRefresh:Bool)->()) {
               
        if pullup && pullupErrorTime > maxPullTryTimes{
            completion(true, false)
            return
        }
        // since_id 下拉,去最大的(第一个)
        let since_id = pullup ? 0 : (statusList.first?.id ?? 0)
        let max_id = pullup ? (statusList.last?.id ?? 0) : 0
        XQWBNetWorkManager.shared.statusList(since_id: since_id, max_id: max_id) { (list, isSuccess) in
            // 1.字典转模型
            guard let array = NSArray.yy_modelArray(with: XQWBStatus.self, json: list ?? []) as? [XQWBStatus] else {
                completion(isSuccess, false)
                return
            }
            if pullup {
                // 上拉
                self.statusList += array
            }else {
                // 下拉刷新
                self.statusList = array + self.statusList;
            }
            if pullup && array.count == 0 {
                self.pullupErrorTime += 1
                completion(isSuccess, false)
            }else {
               completion(isSuccess, true)
            }
        }
    }

6.修改主页之前写的模拟数据加载方法,这里我们就可以使用ViewModel来实现

    listViewModel.loadStatus(pullup: self.isPullup) { (isSuccess, shouldRefresh) in
        self.isPullup = false
        self.refreshControl?.endRefreshing()
        self.tableView?.reloadData()
        if  shouldRefresh {
            self.tableView?.reloadData()
        }
}

7.再次使用access_token请求接口,获取未读微博数量

  • 1.封装专门请求未读数量的网路请求方法

    /// 返回微博未读数量
    func unReadCound(completion:@escaping (_ count:Int)->())  {
        guard let uid = uid else {
            return
        }
        let urlStr = "https://rm.api.weibo.com/2/remind/unread_count.json"
        let params = ["uid":uid]
        tokenRequest(URLString: urlStr, parameters: params) { (json, isSuccess) in
            print(json!)
            let tempJson = json as AnyObject
            let count = tempJson["status"] as? Int
            completion(count ?? 0)
        }
    }
    
  • 2.开启一个定时器,每个一定时间请求未读数量,用来实时监测微博数量

    	  // 设置定时器 
    	  func setupTimer()  {       
    	       timer = Timer.scheduledTimer(timeInterval: 60.0, target: self, selector: #selector(updataTimer), userInfo: nil, repeats:true)
     }
     // 定时器方法
      @objc func updataTimer() {
        XQWBNetWorkManager.shared.unReadCound { (count) in
           print(count)
        }
    }
    
    
  • 3.修改首页tabbarbadge和应用图标badge

    	// 设置首页tabbar
    self.tabBar.items?[0].badgeValue = count > 0 ? "\(count)" : nil
        // APP的badgeNum(授权)
    UIApplication.shared.applicationIconBadgeNumber = count
    
    
  • PS: 在设置应用的badge的时候,我们需要用户的权限

    	 // 判断系统版本
    	  if #available(iOS 10.0, *) {
    	    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .carPlay, .badge]) { (success, error) in
    	        print("授权")
    	    }
    	} else {
    	    // Fallback on earlier versions
    	    // 授权显示通知(状态栏/声音/number)
    	    let notifSettings = UIUserNotificationSettings(types: [.alert, .sound, .badge], categories: nil)
    	    application.registerUserNotificationSettings(notifSettings)
    	}
    
    

8.细心的同学会发现新浪微博官方应用有一个功能,就是当你的首页有未读微博的时候,点击首页的item,tableView就会滚动到最顶部,下边就实现这个功能

  • 1.实现这个功能,我们就需要用到UITabBarControllerDelegate的代理方法,我们整理下思路,写一个伪代码
    	// 1.判断是否在主页
    	// 2.在主页,点击item就滚动到顶部,并且刷新数据
    	// 3.如果不是在主页,跳转到主页
    
  • 2.具体代码如下:
    /// 将要选择item
    ///
    /// - Parameters:
    ///   - tabBarController: tabbar
    ///   - viewController: 目标控制器
    /// - Returns: 是否切换到控制器
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
    
        // 1. 获取控制器所在的索引
        let index = (childViewControllers as NSArray).index(of: viewController)
        // 2. 判断当前是首页,点击是首页
        if selectedIndex == 0 && index == selectedIndex {
            print("点击首页")
            // 让表格滚动到顶部
            let nav = childViewControllers[0] as! UINavigationController
            let vc = nav.childViewControllers[0] as! XQWBHomeViewController
            vc.tableView?.setContentOffset(CGPoint(x: 0, y: -64), animated: true)
    
            // 刷新表格
            DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
                vc.loadData()
            })
        }
        return !viewController.isMember(of: UIViewController.self)
    }
    
    

总结

今天我们主要体验了access_token的作用,对OAuth授权有了一定的了解,通过使用UITabBarControllerDelegate方法,对首页加载进行了优化

往期内容: Swift新浪微博项目更新目录

项目git地址

转载于:https://my.oschina.net/ozawa4865/blog/827762

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值