iOS Demo之NBA球队赛程

最近NBA 2017-2018赛季的比赛日程已经公布出来,作为一个"资深的"NBA球迷、篮球迷,怎么能不赶紧把自己喜欢的球队给比赛日给记下来呢?之前看到过一个JRS()把日历做成链接的形式可以直接把自己比赛直接写入到手机的日历中去,受到这个启发,干嘛不自己亲自动手写一个App,直接把赛程写到手机日历中去呢,而且还可以锻炼自己的编码能力。有了兴趣,然后开始动手,一切就水到渠成了。下面就简单记录一下这个小App的制作过程。

1、确定需求

  1. 球队列表,能够选择自己喜欢的NBA球队。
    ①按照正常的NBA联盟分区,分为东部球队以及西部球队
    ②每个球队展示的信息有名称、Logo、所在分区
  2. 球队赛程列表
    ①每场比赛展示主场、客场球队的信息以及比赛的北京日期、比赛地点等
    ②提供导入日历按钮,点击后将当前展示球队的赛程导入到苹果手机的日历中

2、分析需求、确定数据来源(接口API)

通过分析上面的需求,可以得出主要有两个页面,球队列表页面和球队比赛赛程列表页面。通过查找数据得出需要下面三个接口:

  1. 获取球队列表数据
  2. 获取某球队的比赛赛程信息
  3. 获取球队Logo

经过测试这些接口已经再次确认需求,确认这些接口完全能够满足开发需要。

3、动手开发,写Code

1. 开发球队列表页面

当前页面是一个列表页面,实现方式为一个tableView的group形式。
①定义模型Team,包含名称、代号、城市、分区、联盟分区、联盟分区显示字段、球队logo等字段

 class Team: Mappable {

  var name:String?  //名称
  var code:String?  //代号
  var city:String?  //日期
  var division:String?  //分区
  var conference:String?  //联盟分区
  var displayConference:String? //联盟分区显示
  var imageUrl:String? //球队图片

  required init?(map: Map) {
    
  }

  func mapping(map: Map) {
      name <- map["name"]
      code <- map["code"]
      city <- map["city"]
      division <- map["division"]
      conference <- map["conference"]
      displayConference <- map["displayConference"]
  }

}

②自定义Cell,展示Demo tableView

③通过上面的获取球队列表的接口,使用Alamofire拿到球队列表数据,使用SwiftJson、ObjectMapper将返回的结果转化为Team模型数组。注意以为获取到的球队数据中不包含球队Logo Url,可以通过自定义的Json文件team_logo.json来进行配置,然后通过获取球队Logo的接口获取到对于的球队Logo 的url。

Alamofire.request("http://china.nba.com/static/data/league/conferenceteamlist.json").responseJSON { (response) in
        let result = JSON(response.result.value as Any)
//            print(result)
        let listGroups = result["payload"]["listGroups"].arrayValue
        
        for teams in listGroups{
            var tempArray = [Team]()
            for teamJson in teams["teams"].arrayValue{
//                    print(teamJson["profile"].rawString()!)
                let team = Team(JSONString: teamJson["profile"].rawString()!)
                tempArray.append(team!)
            }
            self.teamsData.append(tempArray)
        }
        self.tableView.reloadData()
    }

④展示球队列表数据,完善细节。
搞定!

球队.png

2. 开发球队赛程列表页面

当前页面是一个列表页面,实现方式为一个tableView的plain形式。实现方式类似上面的球队列表页面。
①定义模型Game,包含日期、比赛地址、主场城市、主场球队、客场球队、客场城市
②自定义Cell,展示Demo tableView
③通过上面的获取球队赛程列表的接口,使用Alamofire拿到球队列表数据,使用SwiftJson、ObjectMapper将返回的结果转化为Game模型数组。
④展示球队赛程列表,完善细节。

赛程.png

3. 导入比赛到手机日历中

点击导入日历按钮,确定后开始执行导入日历功能
这就要用到iOS提供的EventKit框架来实现将比赛写入到日历的功能了。
首先要去获取授权,没有被授权的话是不能使用EventKit框架的,iOS自身框架大部分都有这个限制。而且在iOS 10以上的系统还要添加访问calendar的隐私说明,否则会引起崩溃。

lazy var eventStore = EKEventStore()
// 获取访问日历的权限
self.eventStore .requestAccess(to: .event, completion: { (granted, error) in

        //授权过可以访问日历
        if granted{
            let tempArray = self.eventStore.calendars(for: .event)
            var inserted = false
            for calendar in tempArray{
                print(calendar)
                
                //判断是否已经导入了比赛内容
                if calendar.title == self.team.name {
                    inserted = true
                }
            }
            
            if !inserted {
                self.saveEvent()
            }else{
                DispatchQueue.main.async {
                    CDAlertView(title: "", message: "已经导入过该队比赛!", type: .notification).show()
                }
            }
        }
    })

接下来就可以执行导入时间到日历的功能了。

     self.startAnimating(CGSize(width: 30, height: 30),type:.ballBeat,color: UIColor.init(hexString: "#E0486C"),backgroundColor:UIColor.white)
        
    //    因为是读写操作,比较耗时,需要放到后台去执行。
        DispatchQueue.global().async {
        //把比赛写入日历
  //            print(self.eventStore)
            for game in self.datas{
                
                let event = EKEvent(eventStore: self.eventStore)
                
                // 标题
                let title = game.homeTeamName! + "VS" + game.awayTeamName!
                event.title = title
                
                //时间
                let date = Date.init(timeIntervalSince1970: TimeInterval(Int64(game.gameDate!)!/1000))

                //开始时间、结束时间
                event.startDate = date
                event.endDate = date.addingTimeInterval(150*60)
                //日历
                let calendar = self.eventStore.defaultCalendarForNewEvents
                calendar.title = self.team.name! + "赛程"
                calendar.cgColor = UIColor.purple.cgColor
                event.calendar = calendar
                
                do{
                    try self.eventStore.save(event, span: EKSpan.thisEvent)
                }catch let error as NSError{
                    print(error)
                }
            }
            //结束后,主线程刷新UI
            DispatchQueue.main.async {
                self.stopAnimating()
            }

执行完去查看日历,就能够看到赛程已经写入到日历啦,再也不用担心忘了比赛了。在上面写入赛程的Event,还可以添加多长时间进行提醒的功能。是不是很方便,很简单?

日历.png

项目虽然简单,但是通过代码的方式来解决问题不就是程序猿应该做得,而且通过这些小项目也能学到一些东西,锻炼自己的编码能力。

项目地址:点我,欢迎各位大神前来指导。

推荐阅读更多精彩内容