一:你需要获得某一个服务器网页的接口。(这个可以用抓包软件获取服务器http的头部信息)
音乐歌曲对应的搜索接口HTTP URL请求的地址:
http://music.163.com/api/search/get/web
需要设置的HTTP Haeder:
"Accept-Encoding”: "deflate,gzip"
"Content-Type”: "application/x-www-form-urlencoded"
"Referer”: "http://music.163.com/"
"User-Agent”: "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"
需要设置的HTTP Body:
NSString *body = [NSString stringWithFormat:@"s=%@&limit=%d&offset=%d&type=1”,搜索的关键字,当前返回的搜索结果数量num(num<=100),当前偏移量offset(offset==当前搜索的页数page*每页返回的结果num)];
需要设置的HTTP Method:
POST
当然相关的知识资料请参考:点击打开链接
二:创建一个接口,获取网络数据。(添加一个继承NSObject的FetchDataFromNet类)
1.创建一个类方法,用于获取数据。
+ (void)fetchMusicData:(NSString *)key page:(NSInteger)page callback:(fetchTrackDataAndError)callback;
其中fetchTrackDataAndError是回调方法,至于什么是回调方法,请参考:点击打开链接。
typedef void(^fetchTrackDataAndError)(NSArray *array, NSInteger page, NSError *error);
参数的含义:key,这个是要搜索的歌曲名;page,是第几页;array,是搜到的歌曲放在array中。
FetchDataFromNet.m文件中:
#import "MusicData.h"
// 定义网络路径
#define url @ "http://music.163.com/api/search/get/web"
// 定义可以获取的歌曲数
#define kLimit 1
@implementation FetchDataFromNet
+ ( void )fetchMusicData:( NSString *)key page:( NSInteger )page callback:( fetchTrackDataAndError )callback{
NSURL *musicURL = [ NSURL URLWithString : url];
// 创建该路径下的请求,用来设置 http 头部中的参数和方法类型
NSMutableURLRequest *request = [ NSMutableURLRequest requestWithURL :musicURL];
[request setValue : @"deflate,gzip" forHTTPHeaderField : @"Accept-Encoding" ];
[request setValue : @"application/x-www-form-urlencoded" forHTTPHeaderField : @"Content-Type" ];
[request setValue : @"http://music.163.com/" forHTTPHeaderField : @"Referer" ];
[request setValue : @"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)" forHTTPHeaderField : @"User-Agent" ];
NSLog ( @"%@" ,request);
[request setHTTPMethod : @"POST" ];
NSString *bodyString = [ NSString stringWithFormat : @"s=%@&limit=%d&offset=%ld&type=1" ,key, kLimit ,page * kLimit];
[request setHTTPBody:[bodyString dataUsingEncoding:NSUTF8StringEncoding]];
[ NSURLConnection sendAsynchronousRequest :request queue :[ NSOperationQueue currentQueue ] completionHandler :^( NSURLResponse *response, NSData *data, NSError *connectionError) {
if (connectionError) {
callback( nil ,page,connectionError);
} else {
// 创建一个可变数组,用来存放解析后的歌曲
NSMutableArray *trackMusicData = [ NSMutableArray new ];
@try {
// 创建一个字典用来存储 json 格式解析后的数据
NSDictionary *itemDictionary = [ NSJSONSerialization JSONObjectWithData :data options : kNilOptions error : nil ];
// 打印该字典,看其中的属性。
NSLog ( @"%@" ,itemDictionary);
// 利用属性中的 key 获得歌曲的数组,也就获得了songs数组中的数据
NSArray *itemArray = [[itemDictionary objectForKey : @"result" ] objectForKey : @"songs" ];
// 循环遍历讲歌曲初始化成 MusicData 的对象
[itemArray enumerateObjectsUsingBlock :^( id obj, NSUInteger idx, BOOL *stop) {
MusicData *data = [ MusicData musicDataWithDic :obj];
if (data) {
[trackMusicData addObject :data];
}
}];
}
@catch (NSException *exception) {
}
@finally {
// 调用回调方法,将歌曲传给 array
callback(trackMusicData,page, nil );
}
}
}];
}
@end
当然这需要你在ViewController.m调用一下该类的类方法。
- (void)testData:(NSString *)name page:(NSInteger)pageIndex{
[FetchDataFromNet fetchMusicData:name page:pageIndex callback:^(NSArray *array, NSInteger page, NSError *error){
if (error) {
NSLog(@"error = %@",error);
} else{
}
}];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self testData:@"lo" page:1];
}
这是一个歌曲的信息,有很多的属性,从而可以确定MusicData中需要哪些属性变量了。
2015-05-20 18:13:02.509 GetData[1609:172269] {
code = 200;
result = {
songCount = 300;
songs = (
{
album = {
artist = {
albumSize = 0;
alias = (
);
id = 0;
img1v1 = 0;
img1v1Url = "http://p3.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg";
name = "";
picId = 0;
picUrl = "<null>";
trans = "<null>";
};
copyrightId = 5003;
id = 1633376;
name = "Garden Window";
picId = 562949953429998;
publishTime = 1321286400000;
size = 11;
status = 1;
};
alias = (
);
artists = (
{
albumSize = 0;
alias = (
);
id = 98435;
img1v1 = 0;
img1v1Url = "http://p4.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg";
name = "O'Brother";
picId = 0;
picUrl = "<null>";
trans = "<null>";
}
);
copyrightId = 5003;
duration = 222000;
fee = 0;
ftype = 0;
id = 17755320;
mvid = 0;
name = Lo;
rUrl = "<null>";
rtype = 0;
status = 1;
}
);
};
}
可以看出{songs({({album};{artists});id;duration})}
json的相关知识资料请参考:点击打开链接
2.MusicData类的作用。
上面的类只是我们获得网络数据的接口,然而若是想继续用到这些数据,就需要对该歌曲对象进行标记,主要用key来进行识别。
MusicData.h文件中:
//歌曲的属性
@property(nonatomic,strong)NSString *trackIdentifier;
@property(nonatomic,strong)NSString *albumIdentifier;
@property(nonatomic,strong)NSString *artistIdentifier;
@property(nonatomic,strong)NSString *trackname;
@property(nonatomic,strong)NSString *albumname;
@property(nonatomic,strong)NSString *artistname;
@property(nonatomic,strong)NSString *logoname;
@property(nonatomic,strong)NSString *duration;
//api
+ (id)musicDataWithDic:(NSDictionary *)dic;
MusicData.m文件中:
+ (id)musicDataWithDic:(NSDictionary *)dic{
return [[self alloc] initWithDic:dic];
}
- (id)initWithDic:(NSDictionary *)dic{
if (self = [super init]) {
self.trackIdentifier = [dic objectForKey:@"id"];
self.trackname = [dic objectForKey:@"name"];
self.duration = [dic objectForKey:@"duration"];
//进入字典中的字典去标识,用key去标识内层中的属性
NSDictionary *albumDic = [dic objectForKey:@"album"];
self.albumIdentifier = [albumDic objectForKey:@"id"];
self.albumname = [albumDic objectForKey:@"name"];
NSDictionary *artistDic = [[dic objectForKey:@"artists" ] firstObject];
self.artistIdentifier = [artistDic objectForKey:@"id"];
self.artistname = [artistDic objectForKey:@"name"];
self.logoname = [artistDic objectForKey:@"img1v1Url"];
}
return self;
}
这样就可以在一个UITableVIewController视图控制器中访问这些数据了,可以把数据加载进cell中了。当然这些工作留在下一个的博文中。