文档章节

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

樱黯雨
 樱黯雨
发布于 2017/01/19 13:08
字数 1592
阅读 51
收藏 0

第四天

今天我们主要练习使用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地址

© 著作权归作者所有

樱黯雨
粉丝 3
博文 36
码字总数 22667
作品 0
郑州
程序员
私信 提问
6.新浪微博Swift项目第六天

第六天 终于有时间可以在更新这个swift的demo了,一看时间,已经是8个月以后,swift都已经更新4.0了,但是目前这个demo依然用3.0去写 之前我们完成了新浪微博是授权,并且成功登陆了我们的微博,今...

樱黯雨
2017/09/26
24
0
2.新浪微博Swift项目第二天

第二天 1. 创建文件目录结构,这里,使用的是MVVM的系统架构 2. 创建各个类 3. 在APPDelegate 中设置启用页面 4. 为了方便开发,加入使用OC写的各个分类,并且设置桥接文件 当你在swift项目里边新...

樱黯雨
2016/12/14
65
0
糗百客户端--JokeClient-Swift

JokeClient-Swift 是基于 swift 编写的,用糗事百科的API简单做了一个糗百客户端,可以浏览各种段子,浏览搞笑图片,查看精彩评论等。 本项目仅供学习交流使用,不能用作任何形式的商业用途!内...

叶秀兰
2014/08/13
2.3K
0
8.新浪微博Swift项目第八天

第八天 第八天我们的2个任务, 1. 学习正则表达式,对微博来源进行处理, 2. 对表情包进行封装,处理微博的图文混排. 下边直接开始: 正则表达式 创建一个的分类,封装一个可以过滤微博来源的方法,...

樱黯雨
2017/10/31
14
0
《从零开始学Swift》学习笔记(Day 69)——Swift与Objective-C混合编程之语言

原创文章,欢迎转载。转载请注明:关东升的博客 在Swift语言出现之前,开发iOS或OS X应用主要使用Objective-C语言,此外还可以使用C和C++语言,但是UI部分只能使用Objective-C语言。 选择语言...

tony关东升
2016/03/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

nginx学习笔记

中间件位于客户机/ 服务器的操作系统之上,管理计算机资源和网络通讯。 是连接两个独立应用程序或独立系统的软件。 web请求通过中间件可以直接调用操作系统,也可以经过中间件把请求分发到多...

码农实战
今天
5
0
Spring Security 实战干货:玩转自定义登录

1. 前言 前面的关于 Spring Security 相关的文章只是一个预热。为了接下来更好的实战,如果你错过了请从 Spring Security 实战系列 开始。安全访问的第一步就是认证(Authentication),认证...

码农小胖哥
今天
11
0
JAVA 实现雪花算法生成唯一订单号工具类

import lombok.SneakyThrows;import lombok.extern.slf4j.Slf4j;import java.util.Calendar;/** * Default distributed primary key generator. * * <p> * Use snowflake......

huangkejie
昨天
12
0
PhotoShop 色调:RGB/CMYK 颜色模式

一·、 RGB : 三原色:红绿蓝 1.通道:通道中的红绿蓝通道分别对应的是红绿蓝三种原色(RGB)的显示范围 1.差值模式能模拟三种原色叠加之后的效果 2.添加-颜色曲线:调整图像RGB颜色----R色增强...

东方墨天
昨天
11
1
将博客搬至CSDN

将博客搬至CSDN

算法与编程之美
昨天
13
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部