M Sonar.xcodeproj/project.pbxproj => Sonar.xcodeproj/project.pbxproj +6 -0
@@ 40,6 40,7 @@
CFD908BD2732B1F800FEFD53 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = CFD908BC2732B1F800FEFD53 /* main.m */; };
CFD908C72732C5E800FEFD53 /* PlayerWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = CFD908C52732C5E800FEFD53 /* PlayerWindowController.m */; };
CFD908CB2732CC2800FEFD53 /* PlayerHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = CFD908CA2732CC2800FEFD53 /* PlayerHeaderView.m */; };
+ CFDB4AD22BAB117D00A36AEE /* BRSonicAPIResponseSearchResult.m in Sources */ = {isa = PBXBuildFile; fileRef = CFDB4AD12BAB117D00A36AEE /* BRSonicAPIResponseSearchResult.m */; };
CFDC05452743BE820065F13D /* BRSonicAPISong.m in Sources */ = {isa = PBXBuildFile; fileRef = CFDC05442743BE820065F13D /* BRSonicAPISong.m */; };
CFDC05482743BE9A0065F13D /* BRSonicAPIResponseSongs.m in Sources */ = {isa = PBXBuildFile; fileRef = CFDC05472743BE9A0065F13D /* BRSonicAPIResponseSongs.m */; };
CFDC054B2743C0A50065F13D /* BRSonicAPIResponseAlbums.m in Sources */ = {isa = PBXBuildFile; fileRef = CFDC054A2743C0A50065F13D /* BRSonicAPIResponseAlbums.m */; };
@@ 123,6 124,8 @@
CFD908C52732C5E800FEFD53 /* PlayerWindowController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PlayerWindowController.m; sourceTree = "<group>"; };
CFD908C92732CC2800FEFD53 /* PlayerHeaderView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PlayerHeaderView.h; sourceTree = "<group>"; };
CFD908CA2732CC2800FEFD53 /* PlayerHeaderView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PlayerHeaderView.m; sourceTree = "<group>"; };
+ CFDB4AD02BAB117D00A36AEE /* BRSonicAPIResponseSearchResult.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BRSonicAPIResponseSearchResult.h; sourceTree = "<group>"; };
+ CFDB4AD12BAB117D00A36AEE /* BRSonicAPIResponseSearchResult.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BRSonicAPIResponseSearchResult.m; sourceTree = "<group>"; };
CFDC05432743BE820065F13D /* BRSonicAPISong.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BRSonicAPISong.h; sourceTree = "<group>"; };
CFDC05442743BE820065F13D /* BRSonicAPISong.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BRSonicAPISong.m; sourceTree = "<group>"; };
CFDC05462743BE9A0065F13D /* BRSonicAPIResponseSongs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BRSonicAPIResponseSongs.h; sourceTree = "<group>"; };
@@ 314,6 317,8 @@
CF5849B42A41891A00B494C7 /* BRSonicAPIResponsePlaylist.m */,
CFE160E4279C386E00287C14 /* BRSonicAPIResponseStarred.h */,
CFE160E5279C386E00287C14 /* BRSonicAPIResponseStarred.m */,
+ CFDB4AD02BAB117D00A36AEE /* BRSonicAPIResponseSearchResult.h */,
+ CFDB4AD12BAB117D00A36AEE /* BRSonicAPIResponseSearchResult.m */,
CFD1C4D6273E958B009ED1CD /* BRSonicAPIArtist.h */,
CFD1C4D7273E958B009ED1CD /* BRSonicAPIArtist.m */,
CFDC054C2743C0B90065F13D /* BRSonicAPIAlbum.h */,
@@ 478,6 483,7 @@
CFDC05512743C3870065F13D /* Album.m in Sources */,
CF252E93273E634200A0D26C /* Artist.m in Sources */,
CFC62B2428ACB1F4006E08B6 /* SonarApplication.m in Sources */,
+ CFDB4AD22BAB117D00A36AEE /* BRSonicAPIResponseSearchResult.m in Sources */,
CFDC054B2743C0A50065F13D /* BRSonicAPIResponseAlbums.m in Sources */,
CFB55EAF2781DBA6004F9C47 /* Playlist.m in Sources */,
CFDC054E2743C0B90065F13D /* BRSonicAPIAlbum.m in Sources */,
M Sonar/API Client/BRSonicAPIClient.h => Sonar/API Client/BRSonicAPIClient.h +5 -0
@@ 14,6 14,7 @@
#import "BRSonicAPIResponsePlaylist.h"
#import "BRSonicAPIResponsePlaylistSongs.h"
#import "BRSonicAPIResponseStarred.h"
+#import "BRSonicAPIResponseSearchResult.h"
NS_ASSUME_NONNULL_BEGIN
@@ 53,6 54,10 @@ NS_ASSUME_NONNULL_BEGIN
- (void)getStarredsWithCredential:(BRSonicAPICredential *)credential
completion:(void (^) (NSError * _Nullable error, BRSonicAPIResponseStarred *response))callback;
+- (void)searchWithKeyword:(NSString *)keyword
+ credential:(BRSonicAPICredential *)credential
+ completion:(void (^) (NSError * _Nullable error, BRSonicAPIResponseSearchResult *response))callback;
+
- (void)starWithItem:(id)item
withCredential:(BRSonicAPICredential *)credential
completion:(void (^) (NSError * _Nullable error))callback;
M Sonar/API Client/BRSonicAPIClient.m => Sonar/API Client/BRSonicAPIClient.m +40 -0
@@ 373,6 373,46 @@
}] resume];
}
+- (void)searchWithKeyword:(NSString *)keyword
+ credential:(BRSonicAPICredential *)credential
+ completion:(void (^) (NSError * _Nullable error, BRSonicAPIResponseSearchResult *response))callback {
+ NSURLComponents *components = [NSURLComponents componentsWithURL:credential.host resolvingAgainstBaseURL:NO];
+ [components setPath:@"/rest/search3"];
+
+ [components setQueryItems:
+ [[credential baseUrlQueryItems] arrayByAddingObjectsFromArray:@[
+ [NSURLQueryItem queryItemWithName:@"query" value:keyword],
+ [NSURLQueryItem queryItemWithName:@"artistCount" value:@"500"],
+ [NSURLQueryItem queryItemWithName:@"albumCount" value:@"500"],
+ [NSURLQueryItem queryItemWithName:@"songCount" value:@"500"]
+ ]]];
+
+ [[[NSURLSession sharedSession] dataTaskWithURL:components.URL
+ completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
+ if (error) {
+ callback(error, nil);
+ return;
+ }
+ NSError *rError = nil;
+ BRSonicAPIResponseSearchResult *xml = [[BRSonicAPIResponseSearchResult alloc] initWithData:data
+ options:NSXMLNodeOptionsNone
+ error:&rError];
+ if (rError) {
+ callback(rError, nil);
+ return;
+ }
+ if (xml.status == BRSonicAPIResponseStatusFailed) {
+ callback(xml.error ?: [NSError errorWithDomain:@"net.b123400.sonic"
+ code:0
+ userInfo:@{
+ NSLocalizedDescriptionKey: NSLocalizedString(@"Failed", @"")
+ }], nil);
+ return;
+ }
+ callback(nil, xml);
+ }] resume];
+}
+
- (void)starWithItem:(id)item
withCredential:(BRSonicAPICredential *)credential
completion:(void (^) (NSError * _Nullable error))callback {
A Sonar/API Client/BRSonicAPIResponseSearchResult.h => Sonar/API Client/BRSonicAPIResponseSearchResult.h +18 -0
@@ 0,0 1,18 @@
+//
+// BRSonicAPIResponseSearchResult.h
+// Sonar
+//
+// Created by b123400 on 2024/03/20.
+//
+
+#import "BRSonicAPIResponse.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface BRSonicAPIResponseSearchResult : BRSonicAPIResponse
+
+- (NSArray*)items;
+
+@end
+
+NS_ASSUME_NONNULL_END
A Sonar/API Client/BRSonicAPIResponseSearchResult.m => Sonar/API Client/BRSonicAPIResponseSearchResult.m +33 -0
@@ 0,0 1,33 @@
+//
+// BRSonicAPIResponseSearchResult.m
+// Sonar
+//
+// Created by b123400 on 2024/03/20.
+//
+
+#import "BRSonicAPIResponseSearchResult.h"
+#import "BRSonicAPISong.h"
+#import "BRSonicAPIAlbum.h"
+#import "BRSonicAPIArtist.h"
+
+@implementation BRSonicAPIResponseSearchResult
+
+- (NSArray *)items {
+ NSXMLElement *starredElement = [[self.rootElement elementsForName:@"searchResult3"] firstObject];
+ NSMutableArray *items = [NSMutableArray array];
+ for (NSXMLElement *childElement in starredElement.children) {
+ if ([[childElement name] isEqualTo:@"artist"]) {
+ BRSonicAPIArtist *a = [[BRSonicAPIArtist alloc] initWithXMLElement:childElement];
+ [items addObject:a];
+ } else if ([[childElement name] isEqualTo:@"album"]) {
+ BRSonicAPIAlbum *a = [[BRSonicAPIAlbum alloc] initWithXMLElement:childElement];
+ [items addObject:a];
+ } else if ([[childElement name] isEqualTo:@"song"]) {
+ BRSonicAPISong *a = [[BRSonicAPISong alloc] initWithXMLElement:childElement];
+ [items addObject:a];
+ }
+ }
+ return items;
+}
+
+@end