Reputation: 2312
I'm trying to use the Trakt API to get a list of TV shows and other data. However, I'm stuck on authenticating my app with Trakt. I have my API key, secret, and redirect URI, but am struggling on how to authorise my app. I've tried the following:
Method 1, using the sample code from Trakt:
-(void)authorisation{
NSString *redirectURI = @"http://myappredirect://";
NSString *clientID = @"MY_CLIENT_ID";
NSString *clientSecret = @"MY_CLIENT_SECRET";
NSString *username = @"USERNAME";
NSString *authURL = [NSString stringWithFormat:@"https://trakt.tv/oauth/authorize?response_type=code&client_id=%@&redirect_uri=%@&state=state&username=%@", clientID, redirectURI, username];
NSURL *URL = [NSURL URLWithString:authURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
[request setHTTPMethod:@"GET"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[[UIApplication sharedApplication] openURL:URL];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
// Handle error...
return;
}
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSLog(@"Response HTTP Status code: %ld\n", (long)[(NSHTTPURLResponse *)response statusCode]);
NSLog(@"Response HTTP Headers:\n%@\n", [(NSHTTPURLResponse *)response allHeaderFields]);
}
NSString* body = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"Response Body:\n%@\n", body);
}];
[task resume];
}
This opens Safari on my iPhone, loads the web page successfully with Trakt asking to authorise my account for my app. I tap 'Authorize' and then Safari loads a URL 'myappredirect//?code=a_really_long_string_of_characters
", but with an error
Safari cannot open the page because the server cannot be found.
When I enter myappredirect://
in Safari, my app opens, so I'm wondering if the URL that Safari loads is incorrect as it's missing a semi-colon before the double //?
So I tried adding a UIWebView
to my app and load the URL in there. It loads the URL but this time after I tap 'Authorize', it doesn't change the webpage. The UIWebView
delegate webViewDidStartLoad
does tell me that it loads a page after I tap 'Authorize', but nothing changes on-screen.
Method 2, using OAuth2Client:
-(void)setupWebview{
webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 300, 300)];
webView.backgroundColor = [UIColor greenColor];
webView.delegate = self;
[self.view addSubview:webView];
}
-(void)webViewDidStartLoad:(UIWebView *)webView{
NSLog(@"webViewDidStartLoad");
}
-(void)secondMethod{
NSString *redirectURI = @"http://myappredirect://";
NSString *clientID = @"MY_CLIENT_ID";
NSString *clientSecret = @"MY_CLIENT_SECRET";
NSString *username = @"USERNAME";
NSString *authURL = [NSString stringWithFormat:@"https://api-v2launch.trakt.tv/oauth/authorize?response_type=code&client_id=%@&redirect_uri=%@&state=state&username=%@", clientID, redirectURI, username];
NSString *tokenURL = @"https://api-v2launch.trakt.tv";
[[NXOAuth2AccountStore sharedStore] setClientID:clientID
secret:clientSecret
authorizationURL:[NSURL URLWithString:authURL]
tokenURL:[NSURL URLWithString:tokenURL]
redirectURL:[NSURL URLWithString:redirectURI]
forAccountType:@"Trakt"];
[[NXOAuth2AccountStore sharedStore] requestAccessToAccountWithType:@"Trakt"
withPreparedAuthorizationURLHandler:^(NSURL *preparedURL){
// Open a web view or similar
[webView loadRequest:[NSURLRequest requestWithURL:preparedURL]];
}];
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:YES];
[[NSNotificationCenter defaultCenter] addObserverForName:NXOAuth2AccountStoreAccountsDidChangeNotification
object:[NXOAuth2AccountStore sharedStore]
queue:nil
usingBlock:^(NSNotification *aNotification){
// Update your UI
NSLog(@"Success");
}];
[[NSNotificationCenter defaultCenter] addObserverForName:NXOAuth2AccountStoreDidFailToRequestAccessNotification
object:[NXOAuth2AccountStore sharedStore]
queue:nil
usingBlock:^(NSNotification *aNotification){
NSError *error = [aNotification.userInfo objectForKey:NXOAuth2AccountStoreErrorKey];
// Do something with the error
NSLog(@"Error");
}];
}
Here, I'm not sure what the token URL is. Again, my UIWebView
loads the URL perfectly but after I press 'Authorize', it doesn't change its webpage. The delegate method webViewDidStartLoad
does tell me that it loads another page, but nothing changes on-screen. Also, neither of the NXOAuth2
notifications are sent.
I'm new to OAuth2 and would really appreciate any help anybody may have to offer. I apologise if this is a silly question, I'm really struggling on what to do, and confused as to why Safari won't open my app after I've authorised Trakt.
Thanks.
Upvotes: 4
Views: 3069
Reputation: 17737
Here's how I did it.
You need to define a url scheme that will open your app instead of the browser, which is useful for the redirect at the end of the oauth process.
Let's call it yoururlscheme
for the example, but you can pick whatever you want (eg: "yourappname" in lowercase, or even your bundle identifier "com.example.yourappname")
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>yoururlscheme</string>
</array>
</dict>
</array>
yoururlscheme://oauth/token
based on what you picked in step 1.import SafariServices
class YourViewController: UIViewController {
var oauthSession: SFAuthenticationSession? = nil
func signIn() {
let clientId = "" // your client id
let redirectUri = "yoururlscheme://oauth/token"
let oauthURL = "https://trakt.tv/oauth/authorize?response_type=code&client_id=\(clientId)&redirect_uri=\(redirectUri)"
oauthSession = SFAuthenticationSession(url: oauthURL, callbackURLScheme: redirectUri) { (url, error) in
guard let url = url,
let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false),
let queryItems = urlComponents.queryItems,
let code = queryItems.first(where: {$0.name == "code"})?.value else {
return
}
// Do whatever you want with the token now
print("code: \(code)")
}
oauthSession?.start()
}
}
Upvotes: 2
Reputation: 56
With the UIWebView you have interrupt the load in UIWebView delegate shouldStartLoadWithRequest
when the url starts with your redirect url and get the parameter authorization code from url, concatenate with "get token url" and call [[NXOAuth2AccountStore sharedStore] handleRedirectURL:getTokenURL];
May not be the best way, but it works for me. :)
English isn’t my first language, so please excuse any mistakes. I hope this can help you.
Upvotes: 2
Reputation: 3873
NSString *redirectURI = @"myappredirect://";
instead of
NSString *redirectURI = @"http://myappredirect://";
Upvotes: 3