(IOS)Swift2.0 Radio 程序分析
本文主要分享下楼主在学习Swift编程过程中,对GitHub上的一个开源项目Swift Radio的研究心得。

项目地址:https://github.com/swiftcodex/Swift-Radio-Pro
一、界面

在这个项目中一共包含了6个界面控制器,其中包含了5个用于分别显示电台频道(Swift Radio)、正在播放(Now Playing View)、电台信息(Info View Controller)、app信息(Menu View Controller)和app特征及联系邮箱(About View Controller)的View Controller及一个Navigation Controller。
二、电台歌曲来源及实现原理
本项目通过调用http://www.last.fm/api提供的API从而实现电台功能。楼主将对其调用的API进行简单的介绍及分析。
1)http://[yoururl.com]/json/stations.json 用于获取电台信息,返回格式为JSON。
本项目中, 作者并未使用此API,而是内置JSON格式的电台数据。
2)http://ws.audioscrobbler.com/2.0/?method=track.getInfo&api_key=[api_key]&artist=[artist]&track=[track]&format=json 通过传递api_key,aritst和track三个参数来获取歌曲信息。
例如:http://ws.audioscrobbler.com/2.0/?method=track.getInfo&api_key=9a267c245324cfa4f887366d497d3dd3&artist=The%20Gossip&track=Coal%20To%20Diamonds&format=json

其中name为歌曲名,artist为歌手信息,album为专辑信息。
本项目中, 作者通过获取正在播放的MPMoviePlayerController()中的Metadata得到artist和track参数,再通过将参数传递到API中,获得完整的歌曲信息。
代码具体实现
1) SwiftRadio-Settings.swift

在SwiftRadio-Settings.swift文件中,作者定义了DEBUG_LOG用于判断是否需要显示调试日志。而后又定义了useLocalStatons来进行判断是否使用本地电台数据,如果useLocalStatons为false,则通过stationDataURL来获取电台信息。接着又给出 了apiKey和apiSecret两个参数以备调用前文获取歌曲信息API时使用(apiSecret并未被使用到)。
2) stations.json

这个文件为本地电台信息,通过修改可以增加或删减电台。其中name是电台名称,streamURL是电台的URL,imageURL是电台图片的URL(因为是本地电台,所以图片都已保存在项目文件中,故imageURL一项中直接给了电台图片文件对应的名称)。
3) RadioStation.swift

创建了一个RadioStation class包含了从电台JSON数据中获取的电台的个属性参数。同是设置了一个构造器及一个直接将电台JSON数据转成RadioStation实例的方法。
4) track.swift
创建了一个Track结构,包含了6个Track的属性。其中artworkLoaded用于记录歌曲图片是否已获取,isPlaying纪录歌曲是否已在播放。
5) DataManager.swift


DataManager这个类中主要包含了获取和处理网络数据或是本地数据的方法。其中getStationDataWithSuccess(success: ((metaData: NSData!) -> Void))方法通过访问SwiftRadio-Settings.swift中useLocalStations的值来判断是使用本地电台数据还是网络电台数据。getDataFromFileWithSuccess(success: ((data: NSData) -> Void))和getTrackDataWithSuccess(queryURL: String, success: ((metaData: NSData!) -> Void))分别是调用本地及网络电台数据的两个方法。loadDataFromURL(url: NSURL, completion:(data: NSData?, error: NSError?) -> Void)则是实现从网络获取电台数据的方法。通过NSURLSession来获得网络数据,而后将所得数据传给方法参数中的包含的方程以供之后的处理及使用。
6) StationsViewController.swift






在StationsViewController类中,实现了对所得到的电台数据进行分析和拆解并通过UITableView将其显示出来。loadStationsFromJSON()通过调用DataManager.getStationDataWithSuccess(success: ((metaData: NSData!) -> Void))获取电台数据并将其0保存在stations:[RadioStation]中。再通过TableView方法来将所得数据呈现在UITableView上。通过重写prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)方法来完成将选中的电台传递给NowPlayingViewController。同时通过完成NowPlayingViewControllerDelegate的两个方法artworkDidUpdate(track: Track)和songMetaDataDidUpdate(track: Track)来获取和显示当前播放歌曲的信息。
7) NowPlayingViewController.swift

创建一个radioPlayer = MPMoviePlayerController()并对其进行设置。当调用stationDidChange()方法时,radioPlayer播放当前电台的媒体流。

metadataUpdated(n: NSNotification)方法用于获取radioPlayer正在播放音乐的metadata,通过进行简单的处理获得正在播放音乐的title和artist信息。如果发现currentSongName与获取title不符,说明开始播放一首新的歌曲了,调用resetAlbumArtwork()和queryAlbumArt()来获取新的歌曲信息,并用updateLockScreen()来更新锁屏界面,用songMetaDataDidUpdate(self.track)将新的歌曲信息传给StationsViewController。

通过使用API获取歌曲完整信息。

resetAlbumArtwork()中通过调用updateAlbumArtwork()来实现专辑封面的更新,如果获取专辑封面失败,则使用电台封面代替。

通过使用NSURLSessionDownloadTask来下载专辑图片,将下载完的图片存至track.artworkImage并更新封面图片,锁屏界面及将新数据回传给StationsViewController。

用于更新界面上的buttons和labels。
三、项目实现的一些特征分析
1) 动态正在播放图标






调用AnimationFrames class 中createFrames()方法为nowPlayingImageView.animationImages创建对象。在通过startAnimating()方法来实现动画效果。
2) 在app中打开safari
通过UIApplication.shareApplication().openURL(url)来实现。
3) 后台播放、锁屏播放及锁屏显示歌曲信息
系统开始接受远端事件。

允许后台播

锁屏歌曲信息设置及接受锁屏时对歌曲播放或暂停的控制。
四、发现的一些BUG
在XCode 7.0.1 iPhone 6s plus 模拟器运行下发现的BUG:
1) 内置email功能无法使用,每次点击email跳转到mail app后立即崩溃。
2) NowPlayingViewController 界面上的Volume Bar 无法调节音量。
3) 在NowPlayingViewController界面播放音乐途中暂停后返回StationViewController后,StationViewController左下角动态正在播放图标还在继续播放动画,而后如果点击正下方Now Playing Button返回NowPlayingViewController时,界面显示音乐正在播放,可实际上音乐处于暂停状态,需要点击暂停按钮再点击播放按钮才能恢复。
五、后记
楼主曾经在学习Swift时做过一个电台的app,相比于这个app,楼主之前做的那个就有些粗制烂造了。通过了对这个app的学习,不但是我对Swift2.0中一些新的特征有了一个更好的理解,同时还让我感受到了这个项目的作者有着很强的程序员素质。对于代码的设计有着很强的全局考虑,使得代码非常的简洁易懂。在阅读和测试时也几乎没有遇到什么因为代码看起来混乱而导致的理解困难。这种编程的思路和设计程序的方法是值得今后值得借鉴和学习的。
(IOS)Swift2.0 Radio 程序分析的更多相关文章
- (IOS)BaiduFM 程序分析
本文主要分享下楼主在学习Swift编程过程中,对GitHub上的一个开源app BaiduFM的研究心得. 项目地址:https://github.com/belm/BaiduFM-Swift 一.项 ...
- iOS UI基础-4.0应用程序管理
功能与界面 功能分析: 以九宫格的形式展示应用信息 点击下载按钮后,做出相应的操作 步骤分析: 加载应用信息 根据应用的个数创建对应的view 监听下载按钮点击 整个应用界面: 程序实现 思路 UI布 ...
- [Swift2.0系列]Defer/Guard 基础语法
1.Defer Swift2.0中加入了defer新语法声明.defer译为延缓.推迟之意.那么在Swift2.0中它将被应用于什么位置呢?比如,读取某目录下的文件内容并处理数据,你需要首先定位到文件 ...
- iOS美丽约网络请求分析
网络请求分析html, body {overflow-x: initial !important;}html { font-size: 14px; } body { margin: 0px; padd ...
- Swift2.0语言教程之Swift2.0语言中的标准函数
Swift2.0语言教程之Swift2.0语言中的标准函数 Swift2.0中的标准函数 函数除了可以根据参数列表的有无分为无参函数和有参函数,还可以从定义角度分为用户自定义函数和标准函数两种.以上的 ...
- Swift2.0语言教程之函数的返回值与函数类型
Swift2.0语言教程之函数的返回值与函数类型 Swift2.0中函数的返回值 根据是否具有返回值,函数可以分为无返回值函数和有返回值函数.以下将会对这两种函数类型进行讲解. Swift2.0中具有 ...
- 3 cocos2dx 3.0 源码分析-mainLoop详细
简述: 我靠上面图是不是太大了, 有点看不清了. 总结一下过程: 之前说过的appController 之后经过了若干初始化, 最后调用了displayLinker 的定时调用, 这里调用了函数 ...
- APM程序分析-AC_WPNav.cpp
APM程序分析 主程序在ArduCopter.cpp的loop()函数. /// advance_wp_target_along_track - move target location along ...
- 对Java数组中去除重复项程序分析
我作为一个Java菜鸟,只会用简单的办法来处理这个问题.如果有大神看到,请略过,感激不尽! 所以首先先分析这道题目:数组中重复的数据进行删除,并且要让数组里的数据按原来的顺序排列,中间不能留空. 既然 ...
随机推荐
- 【Android】Android之Action Bar
Action Bar是在窗口上指示用户位置的组件,同时给用户提供导航和操作.使用Action Bar可以让你的应用在不同配置的屏幕上看起来比较一致.在开始之前,先了解一些相关的术语: Action B ...
- env
shell环境变量以及set,env,export的区别 原文链接 一.shell环境变量的分类以及set env export的区别: set:显示(设置)shell变量 包括的私有变量以及用户变量 ...
- win 8.1 安装framework3.5
其实win8的iso上带着net 3.5的功能的,但是并没有随着系统安装二安装上去.所以只要你有跟你系统同个版本的iso文件,就可以实现不联网安装net3.5.首先把装载你的iso.Win8系统可以打 ...
- PDA手持终端在ERP系统仓库管理出入库盘点环节的应用
PDA手持终端在ERP系统仓库管理出入库盘点环节的应用 传统库存管理的数据录入过程,常采用PC机录入数据,或在电脑上结合条码枪扫描条码进行管理(非实时),造成管理上的不便.因而,采用无线(WIFI)手 ...
- POJ3162 Walking Race(树形DP+尺取法+单调队列)
题目大概是给一棵n个结点边带权的树,记结点i到其他结点最远距离为d[i],问d数组构成的这个序列中满足其中最大值与最小值的差不超过m的连续子序列最长是多长. 各个结点到其他结点的最远距离可以用树形DP ...
- cocos3 singleton
class TestSingleton : public CCLayer { public: static TestSingleton* getInstance();//创建一个全局访问点,例如我们常 ...
- JavaScript初学者应注意的七个细节
每种语言都有它特别的地方,对于JavaScript来说,使用var就可以声明任意类型的变量,这门脚本语言看起来很简单,然而想要写出优雅的代码却是需要不断积累经验的.本文利列举了JavaScript初学 ...
- TYVJ P1004 滑雪 Label:记忆化搜索
背景 成成第一次模拟赛 第三道 描述 trs喜欢滑雪.他来到了一个滑雪场,这个滑雪场是一个矩形,为了简便,我们用r行c列的矩阵来表示每块地形.为了得到更快的速度,滑行的路线必须向下倾斜. ...
- HDU 4630 No Pain No Game(树状数组)
题目链接 看的别人的题解,离线之后,按r排序,枚举1-n,利用pre[j],存上次j的倍数出现的位置,树状数组里统计的当前位置到最后的最大值,树状数组是求区间最值其实应该很麻烦的,但是此题用法只是求到 ...
- Shell之sed用法 转滴
通过例子学习sed的用法 1,sed介绍 sed可删除(delete).改变(change).添加(append).插入(insert).合.交换文件中的资料行,或读入其它档的资料到 文> ...