最近NBA 2017-2018賽季的比賽日程已經公布出來,作為一個"資深的"NBA球迷、籃球迷,怎么能不趕緊把自己喜歡的球隊給比賽日給記下來呢?之前看到過一個JRS()把日歷做成鏈接的形式可以直接把自己比賽直接寫入到手機的日歷中去,受到這個啟發,干嘛不自己親自動手寫一個App,直接把賽程寫到手機日歷中去呢,而且還可以鍛煉自己的編碼能力。有了興趣,然后開始動手,一切就水到渠成了。下面就簡單記錄一下這個小App的制作過程。
1、確定需求
- 球隊列表,能夠選擇自己喜歡的NBA球隊。
①按照正常的NBA聯盟分區,分為東部球隊以及西部球隊
②每個球隊展示的信息有名稱、Logo、所在分區 - 球隊賽程列表
①每場比賽展示主場、客場球隊的信息以及比賽的北京日期、比賽地點等
②提供導入日歷按鈕,點擊后將當前展示球隊的賽程導入到蘋果手機的日歷中
2、分析需求、確定數據來源(接口API)
通過分析上面的需求,可以得出主要有兩個頁面,球隊列表頁面和球隊比賽賽程列表頁面。通過查找數據得出需要下面三個接口:
經過測試這些接口已經再次確認需求,確認這些接口完全能夠滿足開發需要。
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()
}
④展示球隊列表數據,完善細節。
搞定!
2. 開發球隊賽程列表頁面
當前頁面是一個列表頁面,實現方式為一個tableView的plain形式。實現方式類似上面的球隊列表頁面。
①定義模型Game,包含日期、比賽地址、主場城市、主場球隊、客場球隊、客場城市
②自定義Cell,展示Demo tableView
③通過上面的獲取球隊賽程列表的接口,使用Alamofire拿到球隊列表數據,使用SwiftJson、ObjectMapper將返回的結果轉化為Game模型數組。
④展示球隊賽程列表,完善細節。
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,還可以添加多長時間進行提醒的功能。是不是很方便,很簡單?
項目雖然簡單,但是通過代碼的方式來解決問題不就是程序猿應該做得,而且通過這些小項目也能學到一些東西,鍛煉自己的編碼能力。
項目地址:點我,歡迎各位大神前來指導。