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

目标:根据我们获得的歌曲,从而对它进行进一步的解析,获取到歌曲的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 框架,以及观察者模式。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值