当前位置:首页 > Windows程序 > 正文

使用GraceNote Web API发展Mac发现音乐信息的应用

2021-03-29 Windows程序

好久没有写博客,最近各种忙,特别忙里忙,今晚难得清闲。写最近完成下一个博客任务的摘要:使用GraceNote的Web API开发一个查询的音乐信息的应用,事实上,并在这些功能的前GraceNote SDK鲍文是一样的,次不使用不论什么SDK。单纯的使用Web API,然后开发的平台从iOS转移到了Mac上。于是,我人生中第一个Mac App Demo就出来了。

GraceNote Web API的官方资料:点击打开链接


首先看下主要的查询和响应的数据格式:

技术分享


能够看到交互的形式是XML。

其实。不论什么调用GraceNote的Web API的消息,都是向一个指定的URL POST XML消息。然后对返回的XML消息进行解析并从中提取出我们想要的信息。以下是程序的一些常数:

NSString * const kWebAPIURL = @"https://c10239232.web.cddbp.net/webapi/xml/1.0/"; // 调用网络接口的URL NSString * const kClientID = @"10239232"; // 你申请的应用的Client ID NSString * const kClientTag = @"46B9ABAD30F0F5EB409C7BFAA13EB2EF"; // 你申请的应用的Client Tag

当中kWebAPIURL就是这个固定的发起请求的URL,注意将c后面的数字替换成你的App的Client ID。

kClient ID和kClient Tag能够从在站点中注冊的App中找到。


在使用GraceNote的Web API进行查询之前,首先要通过App的Client ID和Client Tag来注冊一个User ID,然后在全部兴许查询中都要使用这个User ID和之前的Client ID来进行认证,格式例如以下:

技术分享

首先看看注冊的代码,在注冊成功后我们将其保存到本地的NSUserDefaults中:

// 向GraceNote站点注冊User ID - (void)gn_registerUserID { NSString *registerString = [NSString stringWithFormat:@" <QUERIES> <QUERY CMD=\"REGISTER\"> <CLIENT>%@-%@</CLIENT> </QUERY> </QUERIES>", kClientID, kClientTag]; // 要POST的字符串。CMD=REGISTER表示注冊动作 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:kWebAPIURL]]; [request setHTTPMethod:@"POST"]; NSData *data = [registerString dataUsingEncoding:NSUTF8StringEncoding]; [request setHTTPBody:data]; // 建立NSURLSessionDataTask NSURLSession *session = [NSURLSession sharedSession]; __weak AppDelegate *weakSelf = self; // 防止self和block形成retain cycle NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSLog(@"*** Register ***"); [self showResponseCode:response]; if (data) { NSError *parseError = nil; // 这里使用第三方类库GDataXML解析XML数据,请确保已经安装GDataXML类库 GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data encoding:NSUTF8StringEncoding error:&parseError]; if (parseError) { NSLog(@"Parse Error:%@", [parseError localizedDescription]); weakSelf.app_userID = nil; } else { /** * 返回的XML数据演示样例: <RESPONSES> <RESPONSE STATUS="OK"> <USER>267493051066226693-31C70A189A61B89C0D45A782DCB7C072</USER> </RESPONSE> </RESPONSES> */ GDataXMLElement *rootElement = [doc rootElement]; NSArray *responses = [rootElement elementsForName:kGNResponse]; GDataXMLElement *resp = responses[0]; if (![self gn_requestSucceed:resp]) { return; } NSString *userID = [[resp elementsForName:kGNUser][0] stringValue]; // 将获取到的user id保存起来 weakSelf.app_userID = userID; // 将user id存储到User Defaults中 NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; [userDefaults setObject:userID forKey:kUserID]; [userDefaults synchronize]; NSLog(@"User ID = %@", userID); } } if (error) { NSLog(@"error : %@", [error localizedDescription]); } NSLog(@"--- Register Finished ---"); }]; // 最后一定要用resume方法启动任务 [dataTask resume]; }

全部的任务都能够通过NSURLSessionDataTask来完毕。


然后依据艺术家名,专辑名。歌曲标题,搜索结果的返回范围来发起查询请求(album search):

// 以Artist,Album Title,Track Title为搜索keyword,发起搜索请求 - (void)gn_albumSearchWithArtist:(NSString *)anArtist albumTitle:(NSString *)anAlbumTitle trackTitle:(NSString *)aTrackTitle start:(NSUInteger)startIndex end:(NSUInteger)endIndex { // 首先移除上次残留的查询结果 [_gn_IDs removeAllObjects]; if (startIndex <= 0 || endIndex <= 0 || startIndex > endIndex) { return; } // 设置查询字符串。本次请求属于ALBUM_SEARCH操作 NSString *searchString = [NSString stringWithFormat:@" <QUERIES> <AUTH> <CLIENT>%@-%@</CLIENT> <USER>%@</USER> </AUTH> <QUERY CMD=\"ALBUM_SEARCH\"> <TEXT TYPE=\"ARTIST\">%@</TEXT> <TEXT TYPE=\"ALBUM_TITLE\">%@</TEXT> <TEXT TYPE=\"TRACK_TITLE\">%@</TEXT> <RANGE> <START>%ld</START> <END>%ld</END> </RANGE> </QUERY> </QUERIES>", kClientID, kClientTag, _app_userID, anArtist, anAlbumTitle, aTrackTitle, startIndex, endIndex]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:kWebAPIURL]]; [request setHTTPMethod:@"POST"]; NSData *data = [searchString dataUsingEncoding:NSUTF8StringEncoding]; [request setHTTPBody:data]; // 建立NSURLSessionDataTask并用resume方法启动任务 NSURLSession *session = [NSURLSession sharedSession]; __weak AppDelegate *weakSelf = self; NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSLog(@"*** Album Search ***"); [self showResponseCode:response]; if (data) { NSError *parseError = nil; GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data encoding:NSUTF8StringEncoding error:&parseError]; if (parseError) { NSLog(@"Parse Error:%@", [parseError localizedDescription]); } else { /** * 请求成功。返回XML结果演示样例: <RESPONSES> <RESPONSE STATUS="OK"> <RANGE> <COUNT>2</COUNT> <START>1</START> <END>2</END> </RANGE> <ALBUM ORD="1"> <GN_ID>7552265-4E82AF73CE400EDC94DCDA49547C585F</GN_ID> <ARTIST>The Carpenters</ARTIST> <TITLE>Now & Then</TITLE> <PKG_LANG>ENG</PKG_LANG> <DATE>1973</DATE> <GENRE NUM="61365" ID="25333">70's Rock</GENRE> <MATCHED_TRACK_NUM>6</MATCHED_TRACK_NUM> <TRACK_COUNT>15</TRACK_COUNT> <TRACK> <TRACK_NUM>6</TRACK_NUM> <GN_ID>7552271-366ED2D1FEB61E8D720D4941009C91A9</GN_ID> <TITLE>Yesterday Once More</TITLE> </TRACK> </ALBUM> <ALBUM ORD="2"> <GN_ID>19546461-AA0668FE5972459884664A7C3FE9D9C2</GN_ID> <ARTIST>The Carpenters</ARTIST> <TITLE>Now And Then</TITLE> <PKG_LANG>ENG</PKG_LANG> <GENRE NUM="61365" ID="25333">70's Rock</GENRE> <MATCHED_TRACK_NUM>6</MATCHED_TRACK_NUM> <TRACK_COUNT>8</TRACK_COUNT> <TRACK> <TRACK_NUM>6</TRACK_NUM> <GN_ID>19546467-560982E049BFF85016AB89C37513F474</GN_ID> <TITLE>Yesterday Once More</TITLE> </TRACK> </ALBUM> </RESPONSE> </RESPONSES> */ GDataXMLElement *rootElement = [doc rootElement]; NSArray *responses = [rootElement elementsForName:kGNResponse]; if ([responses count]) { GDataXMLElement *resp = [responses firstObject]; if (![self gn_requestSucceed:resp]) { return; } GDataXMLElement *range = [resp elementsForName:kGNRange][0]; if (!range) { // 假设没有返回range元素。那么抓取数据失败 NSLog(@"Fail to search album"); return; } NSUInteger count = (NSUInteger)[[[range elementsForName:kGNCount][0] stringValue] integerValue]; NSUInteger start = (NSUInteger)[[[range elementsForName:kGNStart][0] stringValue] integerValue]; if (count <= 0) { // 没有搜索到结果,直接返回 [self showSearchResultsCountText:0]; return; } p_currentPage = start / 10 + 1; p_allPages = count / 10; NSUInteger i = (count - count / 10 * 10) ?

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/69845.html