1.打开项目QQMusic,然后点菜单:“File-New-Target”添加appleWatch扩展项

2.选择Swift语言,把Include Notification Scene前的勾去掉 (项目暂时不需要做ios端的通知)

3.在 WatchKit Extension的Compile Sources 中添加QQMusic项目的需要使用的类文件

4.在QQMusic WatchKit Extension包的Images.xcassets里添加资源图片

并且在QQMusic WatchKit App的Images.xcassets里资源添加图片

(这两个的区别是,WatchKit Extension的图片是在代码里调用,而WatchKit App的图片是storyboard调用)

5.打开Interface.storyboard进行布局


6.关联各个控件IBOutLet

class InterfaceController: WKInterfaceController {

    @IBOutlet weak var iconImage: WKInterfaceImage!
    @IBOutlet weak var titleLabel: WKInterfaceLabel!
    @IBOutlet weak var lrcLabel:WKInterfaceLabel!
    @IBOutlet weak var playButton: WKInterfaceButton!
}

7.加载网络mp3列表

  override func willActivate() {
        super.willActivate()
         {
            //请求列表数据
            provider.getSongList { (results) -> () in
                let errorCode:NSInteger=results["error_code"] as NSInteger
                let result:NSDictionary=results["result"] as NSDictionary
                ) {
                    let resultData:NSArray = result["songlist"] as NSArray
                    var list=[Song]()
                    ;index<resultData.count;index++){
                        var dic:NSDictionary = resultData[index] as NSDictionary
                        var song:Song=Song()
                        song.setValuesForKeysWithDictionary(dic as NSDictionary)
                        list.append(song)
                    }
                    self.tableData=list
                    self.setCurrentSong(list[] as Song)
                }
            }
        }
    }

说明:willActivate方法是在页面显示前调用。

8.加载当前mp3文件,和歌词数据

 func setCurrentSong(song:Song){
      titleLabel.setText("\(song.title)-\(song.author)")
      iconImage.setImage(getImageWithUrl(song.pic_premium))
      self.audioPlayer.stop()
        isPlaying=false
      self.playButton.setBackgroundImage(UIImage(named: "player_btn_play_normal.png"))
      getCurrentMp3(song)
      getCurrentLrc(song.lrclink)
        timer?.invalidate()
        timer=NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: "updateTime", userInfo: nil, repeats: true)
    }

    //获取当前mp3
    func getCurrentMp3(song:Song){
        provider.getSongMp3(song, reciveBlock: { (results) -> () in
            self.audioPlayer.contentURL=NSURL(string: results)
        })
    }

    //获取歌词
    func getCurrentLrc(lrclick:NSString){
        currentLrcData=parseLyricWithUrl(lrclick)?
    }
 //更新播放时间
    func updateTime(){
        //显示歌词
        if currentLrcData != nil {
            let c=audioPlayer.currentPlaybackTime
            if c>0.0{
                let all:Int=Int(c)
                // 查找比当前秒数大的第一条
                var predicate:NSPredicate = NSPredicate(format: "total < %d", all)!
                var lrcList:NSArray = currentLrcData!.filteredArrayUsingPredicate(predicate)
                {
                    var lrcLine:SongLrc = lrcList.lastObject as SongLrc
                    lrcLabel.setText(lrcLine.text)
                }
            }
        }
    }

9.播放、暂停当前歌曲

@IBAction func playSong() {
        if(isPlaying==true){
            //停止播放
            self.audioPlayer.pause()
            self.playButton.setBackgroundImage(UIImage(named: "player_btn_play_normal.png"))
            isPlaying=false
        }else{
            //开始/继续播放
            self.audioPlayer.play()
            self.playButton.setBackgroundImage(UIImage(named: "player_btn_pause_normal.png"))
            isPlaying=true
        }
    }

10.实现上一首下一首歌曲的播放

 //上一首
    @IBAction func preSong() {
        ){
            currentIndex--
        }
        currentSong=tableData[currentIndex]
        setCurrentSong(currentSong)
    }

    //下一首
    @IBAction func nextSong() {
        if(currentIndex < tableData.count){
            currentIndex++
        }
        currentSong=tableData[currentIndex]
        setCurrentSong(currentSong)
    }

11.在storyBoard新建一个InterfaceController,并拖一个table控件(用于显示所有歌曲列表),将其关联SongListController

import Foundation
import WatchKit

class SongListController:WKInterfaceController {
    var dataSource=[Song]()
    //列表控件
    @IBOutlet weak var table: WKInterfaceTable!

    //接收传过来的数据
    override func awakeWithContext(context: AnyObject?) {
        super.awakeWithContext(context)
        if let data = context as? [Song]{
           self.dataSource=data
        }
    }

    //显示列表数据
    override func willActivate() {
        super.willActivate()
        table.setNumberOfRows(dataSource.count, withRowType: "SongRowType")
        for (index, song) in enumerate(dataSource) {
            if let row = table.rowControllerAtIndex(index) as? SongRowController {
                row.titleLabel.setText(song.title)
                row.subTitleLabel.setText(song.author)
            }
        }
    }

    //点击某一行返回
    override func table(table: WKInterfaceTable, didSelectRowAtIndex rowIndex: Int) {
         let song = dataSource[rowIndex]
         self.dismissController()
    }
}
12.将table控件里的rowcontroller关联SongRowController.swift
import Foundation
import WatchKit

class SongRowController:NSObject {
    @IBOutlet weak var titleLabel: WKInterfaceLabel!
    @IBOutlet weak var subTitleLabel: WKInterfaceLabel!
}

13.按住control键,从每一个controller拖到第二个,进行页面跳转

14.在InterfaceController.swift的contextForSegueWithIdentifier方法中设置跳转页面时的传参
   //页面使用storyBoard跳转时传参
    override func contextForSegueWithIdentifier(segueIdentifier: String) -> AnyObject? {
        NSLog("segueIdentifier%@", segueIdentifier)
        if segueIdentifier == "songListSegue"{
            return self.tableData
        }else{
            return nil
        }
    }

15.在SongListController.swift中的awakeWithContext方法,接收传过来的参数

 //接收传过来的数据
    override func awakeWithContext(context: AnyObject?) {
        super.awakeWithContext(context)
        if let data = context as? [Song]{
           self.dataSource=data
        }
    }

16.进行歌曲列表的数据绑定

 //显示列表数据
    override func willActivate() {
        super.willActivate()
        table.setNumberOfRows(dataSource.count, withRowType: "SongRowType")
        for (index, song) in enumerate(dataSource) {
            if let row = table.rowControllerAtIndex(index) as? SongRowController {
                row.titleLabel.setText(song.title)
                row.subTitleLabel.setText(song.author)
            }
        }
    }

最终效果如下:

  

源码下载地址:http://download.csdn.net/detail/fangwulongtian/8584863

转载请注明来源:http://www.cnblogs.com/wuxian/p/4418116.html

Swift实战-QQ在线音乐(AppleWatch版)的更多相关文章

  1. Swift实战-QQ在线音乐(第二版)

    此版本使用百度音乐接口,原因是豆瓣接口很多歌曲没办法找到歌词. 此版本添加了歌词的显示.上一曲.下一曲的实现.歌曲列表指明当前歌曲. 下面来看一下实现过程>>> 一.项目准备: 百度 ...

  2. Swift实战-QQ在线音乐(第一版)

    //一.*项目准备 1.QQ音乐App 界面素材:(我使用PP助手,将QQ音乐App备份,解压ipa文件 即可得到里面的图片素材) 2.豆瓣电台接口:"http://douban.fm/j/ ...

  3. javascript版QQ在线聊天挂件

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. Swift实战-豆瓣电台(五)播放音乐

    观看地址 http://v.youku.com/v_show/id_XNzMwODM0MzI0.html 在这节里面,我们简单学习了一下MediaPlayer的使用 引入媒体框架 import Med ...

  5. python 开发在线音乐播放器-简易版

    在线音乐播放器,使用python的Tkinter库做了一个界面,感觉这个库使用起来还是挺方便的,音乐的数据来自网易云音乐的一个接口,通过urllib.urlopen模块打开网址,使用Json模块进行数 ...

  6. Andriod小项目——在线音乐播放器

    转载自: http://blog.csdn.net/sunkes/article/details/51189189 Andriod小项目——在线音乐播放器 Android在线音乐播放器 从大一开始就已 ...

  7. 微信公众平台中添加qq在线聊天代码

    微信公众平台是个不错的媒体,可以和你的小伙伴们即时交流,但你的小伙伴们是用手机上的微信,打字自然就慢了:有人说用微信网页版,那个也不习惯,再说也不一定所有人都知道网页版微信.(2014.01.22更新 ...

  8. Swift实战-豆瓣电台(九)简单手势控制暂停播放(全文完)

    Swift实战-豆瓣电台(九)简单手势控制暂停播放 全屏清晰观看地址:http://www.tudou.com/programs/view/tANnovvxR8U/ 这节我们主要讲UITapGestu ...

  9. Swift实战-豆瓣电台(八)播放进度与时间

    视频观看地址:http://www.tudou.com/programs/view/4mEtz8S72k0/?resourceId=399000367_06_02_99 这节主要内容是NSTimer, ...

随机推荐

  1. .NET基础拾遗(4)委托、事件、反射与特性

    Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...

  2. 《ASP.NET MVC高级编程(4版)》读书笔记(5)表单和HTML辅助方法

    5.1 表单使用 5.1.1 action 和 method 特性 <form action="/Home/Index">     <input name=&qu ...

  3. ArcGIS10的附件功能

    转自 积思园 http://blog.csdn.net/linghe301/article/details/6386176 老是忘记怎么使用这个ArcGIS10的附件功能,这次就做个记录吧. 在项目应 ...

  4. ROS 5.x自动定时备份并发送到邮箱(实用)

    博主使用ROS已经有很长一段时间了,但经常会忘记备份配置与数据库,加上ROS本身自带的User-Man数据库并不是非常稳定,1年中总会出现1-2次数据丢失的情况.所以费了一定功夫才找到真正可用自动备份 ...

  5. 解除Team Foundation Server 5个用户的限制

    因为所有的用户必须加入到Team Foundation Licensed Users组内才能连接上TFS; 所以只要手工修改数据库,就可以破解5用户限制了.我们以TFSGuest4帐户做测试. 具体操 ...

  6. unity 状态机 + svn + 码云 上篇

    最近刚找到在实习,忙于公司一个c++ 项目 ,一直想写博客来着,没时间写今天熬夜打算先献上自己前几天自己封装的一个fsm状态机 话不多说,直接上正题,这篇博客主要是在学校的时候状态机一直使用的是pla ...

  7. DALSA Coreco - 图像处理软件(Sapera LT )

    http://blog.csdn.net/linglongyouzhi/article/details/3505845 概述 Sapera LT 是一套用于图像采集.显示和控制的独立于硬件以外的 C ...

  8. RHEL安装docker-compose

    Note that Compose 1.5.2 requires Docker 1.7.1 or later. pip install docker-compose==1.5.2 Note that ...

  9. Objective-C ,ios,iphone开发基础:多个视图(view)之间的切换,以及视图之间传值。

    所有的视图都继承自 UIViewController,都使用 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nib ...

  10. V-rep学习笔记:切削

    V-REP allows you to perform cutting simulations. The user can model almost any type of cutting volum ...