您的位置:首页 > 移动开发 > IOS开发

IOS菜鸟的所感所思(五)——对歌曲地址的获取与解析

2015-05-26 22:41 281 查看

目标:根据我们获得的歌曲,从而对它进行进一步的解析,获取到歌曲的MP3地址,从而去实现歌曲的播放。

HTTP URL请求的地址:
http://music.163.com/api/song/detail?ids=[%@],传入歌曲的id
歌曲播放的MP3地址接口:

"Accept-Encoding”: "deflate,gzip"

"Referer”: "http://music.163.com/"

"User-Agent”: "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"

需要设置的HTTP Method:

GET

一:歌曲地址接口的解析。

当然这种获取网络数据的代码还是放在FetchDataFromNet类的接口中。与之前获取歌曲信息的处理一样,需要一个回调方法,和一个类方法。回调方法中传回的信息应该是歌曲MP3的地址,而类方法中的参数应该是一个歌曲的信息(需要进一步解析的MusicData的对象,两个概念不要弄混淆了)。

typedefvoid(^fetchDetailSongInfoCallback)(id
item,NSError *error);

+ (void)fetchSongDetailInfo:(id)item callback:(fetchDetailSongInfoCallback)callback;

具体实现:
1.获取歌曲的id,参数是MusicData的对象,可以根据[item valueForKey:@"trackIdentifier"]获取属性trackIdentifier的值。
2.发送URLRequest,绑定歌曲的地址
3.设置http的头部信息和方法的类型
4.建立网络连接,发送异步请求
5.将数据用JSON格式解析后打印输出,根据字典的结构,从而进一步解析获取歌曲的MP3地址
6.最终调用回调方法,得到歌曲的MP3地址

+ (void)fetchSongDetailInfo:(id)item callback:(fetchDetailSongInfoCallback)callback{

NSURL *songURL = [NSURL
URLWithString:[NSString
stringWithFormat:@"http://music.163.com/api/song/detail?ids=[%@]",[item
valueForKey:@"trackIdentifier"]]];

NSMutableURLRequest *request = [NSMutableURLRequest
requestWithURL:songURL];

[request setValue:@"deflate,gzip"
forHTTPHeaderField:@"Accept-Encoding"];

[request setValue:@"http://music.163.com/"
forHTTPHeaderField:@"Referer"];

[request setValue:@"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"
forHTTPHeaderField:@"User-Agent"];
[request
setHTTPMethod:@"GET"];

[NSURLConnection
sendAsynchronousRequest:request
queue:[NSOperationQueue
currentQueue] completionHandler:^(NSURLResponse *response,
NSData *data, NSError *connectionError) {

if (connectionError) {
callback(nil,connectionError);
}else{

NSString *songID;

@try {

NSDictionary *itemDictionary = [NSJSONSerialization
JSONObjectWithData:data
options:kNilOptions
error:nil];

NSLog(@"%@",itemDictionary);
songID = [[[itemDictionary
objectForKey:@"songs"]firstObject]objectForKey:@"mp3Url"] ;

NSLog(@"%@",songID);
}

@catch (NSException *exception) {

}

@finally {
callback(songID,nil);
}
}

}];

}

注意:NSLog(@"%@",itemDictionary);打印输出字典的详细信息,可以看到:(这是我简化后的形式)

{

songs = (
{
commentThreadId = "R_SO_4_1297650";
copyFrom = "";
copyrightId = 0;
crbt = "<null>";
dayPlays = 0;
disc = "";
duration = 265000;
fee = 0;
ftype = 0;
hearTime = 0;
id = 1297650;
mp3Url = "http://m1.music.126.net/PXzmH5qPC7z83LnXRrgf6g==/2076977464870415.mp3";
mvid = 32973;
name = "Love the Way You Lie [Clean]";
no = 1;
playedNum = 0;
popularity = 100;
position = 1;
ringtone = "";
rtUrl = "<null>";
rtUrls = (
);
rtype = 0;
rurl = "<null>";
score = 100;
starred = 0;
starredNum = 0;
status = 1;
}
);
}
字典结构:{songs =({})}
小括号表示是一个数组,而大括号表示的是字典,了解了结构才能正确的去解析字典
songID = [[[itemDictionary objectForKey:@"songs"]firstObject]objectForKey:@"mp3Url"]
;

所以先用key(songs),接着获取数组中的第一个对象,再将mp3Url作为key获得MP3的值
这样歌曲的MP3地址获取的接口就完成了,接着只需要在需要调用它的地方使用它既可。(不过要传入正确的参数才行)

接着需要考虑的是我们会在什么地方用到这个接口,就是在SearchSongVC试图控制器中点击cell时会调用接口

SearchSongVC.m文件中:

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath
*)indexPath{

MusicData *musicData =
self.getDataArray[indexPath.row] ;
[self
getSongID:musicData];

}
- (void)getSongID:(MusicData *)musicData{
[FetchDataFromNet
fetchSongDetailInfo:musicData
callback:^(id item,
NSError *error){

if (error) {

NSLog(@"error = %@",error);
}else{

NSLog(@"%@",item);

[self.playMusic
playMusic:item];
}
}];

}
首先获得点击cell那行的对象,因为之前我所有的歌曲对象都放在本地数组中getDataArray中,获得MusicData的对象后,用于参数传入方法中,代码中多次地方有NSLog语句是为了测试的方便,看程序执行到了哪里,[self.playMusic playMusic:item];这是另外的接口调用,用于实现歌曲的播放。
这个功能的实现将会放在下一文章中,将会用到AVFoundation框架,以及观察者模式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐