本文主要分享下楼主在学习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 程序分析的更多相关文章

  1. (IOS)BaiduFM 程序分析

    本文主要分享下楼主在学习Swift编程过程中,对GitHub上的一个开源app BaiduFM的研究心得. 项目地址:https://github.com/belm/BaiduFM-Swift 一.项 ...

  2. iOS UI基础-4.0应用程序管理

    功能与界面 功能分析: 以九宫格的形式展示应用信息 点击下载按钮后,做出相应的操作 步骤分析: 加载应用信息 根据应用的个数创建对应的view 监听下载按钮点击 整个应用界面: 程序实现 思路 UI布 ...

  3. [Swift2.0系列]Defer/Guard 基础语法

    1.Defer Swift2.0中加入了defer新语法声明.defer译为延缓.推迟之意.那么在Swift2.0中它将被应用于什么位置呢?比如,读取某目录下的文件内容并处理数据,你需要首先定位到文件 ...

  4. iOS美丽约网络请求分析

    网络请求分析html, body {overflow-x: initial !important;}html { font-size: 14px; } body { margin: 0px; padd ...

  5. Swift2.0语言教程之Swift2.0语言中的标准函数

    Swift2.0语言教程之Swift2.0语言中的标准函数 Swift2.0中的标准函数 函数除了可以根据参数列表的有无分为无参函数和有参函数,还可以从定义角度分为用户自定义函数和标准函数两种.以上的 ...

  6. Swift2.0语言教程之函数的返回值与函数类型

    Swift2.0语言教程之函数的返回值与函数类型 Swift2.0中函数的返回值 根据是否具有返回值,函数可以分为无返回值函数和有返回值函数.以下将会对这两种函数类型进行讲解. Swift2.0中具有 ...

  7. 3 cocos2dx 3.0 源码分析-mainLoop详细

    简述:   我靠上面图是不是太大了, 有点看不清了.  总结一下过程: 之前说过的appController 之后经过了若干初始化, 最后调用了displayLinker 的定时调用, 这里调用了函数 ...

  8. APM程序分析-AC_WPNav.cpp

    APM程序分析 主程序在ArduCopter.cpp的loop()函数. /// advance_wp_target_along_track - move target location along ...

  9. 对Java数组中去除重复项程序分析

    我作为一个Java菜鸟,只会用简单的办法来处理这个问题.如果有大神看到,请略过,感激不尽! 所以首先先分析这道题目:数组中重复的数据进行删除,并且要让数组里的数据按原来的顺序排列,中间不能留空. 既然 ...

随机推荐

  1. C#中使用ListView动态添加数据不闪烁并显示当前插入值

    首先,自定义一个类ListViewNF,继承自 System.Windows.Forms.ListView class ListViewNF : System.Windows.Forms.ListVi ...

  2. cf 333b

    G - Chips Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit S ...

  3. http://jingyan.baidu.com/article/bad08e1ee14ae409c85121cf.html

    http://jingyan.baidu.com/article/bad08e1ee14ae409c85121cf.html

  4. 模拟 Codeforces Round #203 (Div. 2) C. Bombs

    题目地址:http://codeforces.com/problemset/problem/350/C /* 题意:机器人上下左右走路,把其他的机器人都干掉要几步,好吧我其实没读懂题目, 看着样例猜出 ...

  5. MVC 使用HandleErrorAttribute统一处理异常

    HandleErrorAttribute继承自FilterAttribute,且实现了IExceptionFilter接口. 属于AOP思想的一种实现,MVC的四大筛选器(权限,动作,结果,异常)中的 ...

  6. SPOJ839 Optimal Marks(最小割)

    题目大概说给一张图,每个点都有权,边的权等于其两端点权的异或和,现已知几个点的权,为了使所有边的边权和最小,其他点的权值该是多少. 很有意思的一道题,完全看不出和网络流有什么关系. 考虑每个未知的点$ ...

  7. POJ1511 Invitation Cards(多源单汇最短路)

    边取反,从汇点跑单源最短路即可. #include<cstdio> #include<cstring> #include<queue> #include<al ...

  8. VS 2010 WebSite网站 使用CodeBehide 方式开发[Web应用程序项目转Web网站]

    由于生成Web应用程序的文件非常大,100M左右,上传到香港太慢,对于运维工作很不现实, 所以只能改用单个源代码文件上传方式,也就是Web网站方式,但VS2010中只提供Web网站转Web应用程序功能 ...

  9. Vijos 1100 (区间DP)

    题目链接: https://vijos.org/p/1100 题目大意:NOIP著名的加分二叉树.给出一棵树的中序遍历,加分规则左子树*右子树+根.空子树分数为1.问最大加分的树结构,输出树结构的先序 ...

  10. 产品原型设计工具 Balsamiq Mockups(转)

    Balsamiq Mockups是产品设计师绘制线框图或产品原型界面的利器.在产品设计的需求阶段,低保真的线框图或者草图设计介于产品流程设计与高保真DEMO设计之间,在Balsamiq Mockups ...