We're building a small Unity/iOS application with an Objective-C plug-in to provide access to MusicKit. I'm going through the announcement talk which takes you through the process to access each component of MusicKit.
We've ticked off:
- Authorization to Media Library
- User Capabilities
- Getting Storefront Access code
Now we're onto the user token request and it's failing every time with the error SKErrorDomain Code=7, otherwise known as SKErrorCloudServiceNetworkConnectionFailed. The localised description written within the errors is 'Cannot connect to iTunes Store'. The final underlying error states that the HTTP status being returned is a 401 Unauthorized. See the full log of the response error here:
Error Domain=SKErrorDomain Code=7 "(null)" UserInfo={NSUnderlyingError=0x283058c60 {Error Domain=SSErrorDomain Code=109 "(null)" UserInfo={NSUnderlyingError=0x2830589f0 {Error Domain=SSErrorDomain Code=109 "Cannot connect to iTunes Store" UserInfo={NSLocalizedDescription=Cannot connect to iTunes Store, SSErrorHTTPStatusCodeKey=401}}}}}
I've found other responses to this particular error being cited as a bad developer token. This is potentially backed up as if I change the developer token in any way (replaced some random characters with 0s), I get the same response from the request, exactly as above with the same number of underlying errors.
However, if I use 'Postman' go through the process of sending requests through the Web API instead, using the developer token as a Bearer Authorization token, I get valid 200 OK responses from a request to, for example:
https://api.music.apple.com/v1/catalog/gb/songs/1161539476
If I alter the token in any way, this GET request returns a 401 Unauthorized response.
I've provided the relevant code below, redacted all irrelevant code. Any help would be really appreciated:
#import <Foundation/Foundation.h> #import <StoreKit/StoreKit.h> @interface MusicKitPlugin : NSObject { } @end @implementation MusicKitPlugin static MusicKitPlugin *_sharedInstance; SKCloudServiceController *_csController; NSString *_developerToken; NSString *_userToken; +(MusicKitPlugin*) sharedInstance { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSLog(@"Creating MusicKitPlugin shared instance"); _sharedInstance = [[MusicKitPlugin alloc] init]; }); return _sharedInstance; } -(id)init { self = [super init]; if (self) { _csController = [SKCloudServiceController new]; _developerToken = @"{INSERT_DEV_TOKEN}"; _userToken = @""; } return self; } -(void)requestUserToken { NSLog(@"Request user token called"); [_csController requestUserTokenForDeveloperToken:_developerToken completionHandler:^(NSString *userToken, NSError *error) { NSLog(@"User token request responded"); if(userToken != NULL) { NSLog(@"User token: %@", userToken); _userToken = userToken; } else if (error != NULL) { [self handleError:error]; } }]; } -(void)handleError:(NSError *)error { NSLog(@"Error: %@", error); NSLog(@"Error domain: %@", [error domain]); NSLog(@"Error code: %ld", [error code]); NSLog(@"Error user info: %@", [error userInfo]); switch ([error code]) { ... case SKErrorCloudServiceNetworkConnectionFailed: NSLog(@"Cloud service network connection failed"); break; ... } } @end extern "C" { void IOS_RequestUserToken() { [[MusicKitPlugin sharedInstance] requestUserToken]; } }
So I tap a button in Unity, that button calls the IOS_RequestUserToken method that is linked to in a MonoBehaviour in Unity from the Objective-C plug-in. That calls the requestUserToken function of the shared instance plug-in and it outputs:
Request user token called User token request responded Error: Error Domain=SKErrorDomain Code=7 "(null)" UserInfo={NSUnderlyingError=0x283058c60 {Error Domain=SSErrorDomain Code=109 "(null)" UserInfo={NSUnderlyingError=0x2830589f0 {Error Domain=SSErrorDomain Code=109 "Cannot connect to iTunes Store" UserInfo={NSLocalizedDescription=Cannot connect to iTunes Store, SSErrorHTTPStatusCodeKey=401}}}}} Error domain: SKErrorDomain Error code: 7 Error user info: { NSUnderlyingError = "Error Domain=SSErrorDomain Code=109 \"(null)\" UserInfo={NSUnderlyingError=0x2830589f0 {Error Domain=SSErrorDomain Code=109 \"Cannot connect to iTunes Store\" UserInfo={NSLocalizedDescription=Cannot connect to iTunes Store, SSErrorHTTPStatusCodeKey=401}}}"; } Cloud service network connection failed