application:openURL:options: not called
Nobody has claimed this yet.
- Dominant language
- Objective-C
- Stars
- 2k
- Forks
- 867
- Avg merge
- 4d 48m
- Merged PRs (30d)
- 1
Description
I'm using this in Flutter where I have just the rootViewController. It all works well I can login, the server redirects to the custom scheme of the app.
In my case I redirect the code to the my backend server and from there to the app. After the server responds the app pops up but the callback is not called, nether the application:openURL:options:
What am I missing.
#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"
static NSString *const kAppAuthExampleAuthStateKey = @"authState";
@implementation AppDelegate {
OIDServiceConfiguration *configuration;
OIDAuthState *authState;
FlutterResult flutterResult;
}
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
FlutterViewController *controller = (FlutterViewController *) [[self window] rootViewController];
FlutterMethodChannel *channel =
[FlutterMethodChannel methodChannelWithName:@"app_channel" binaryMessenger: controller];
[channel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
[self onMethodCall:call result:result];
}];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
- (void) onMethodCall:(FlutterMethodCall *)call result:(FlutterResult )result {
if([@"init" isEqualToString:call.method]){
OIDServiceDiscovery *doc = [[OIDServiceDiscovery alloc] initWithJSON:call.arguments error:nil];
configuration = [[OIDServiceConfiguration alloc] initWithDiscoveryDocument:doc];
} else if([@"authorize" isEqualToString:call.method]) {
if (flutterResult) {
flutterResult = nil;
@throw [NSInvalidArgumentException initWithString:@"Already login in."];
}
flutterResult = result;
NSString *jsonString = call.arguments[@"params"];
NSStringEncoding encoding = 0;
NSData *jsonData = [jsonString dataUsingEncoding:encoding];
NSError *error=nil;
NSDictionary *params = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
NSMutableDictionary *additionalParameters = [[NSMutableDictionary alloc] initWithDictionary: params[@"additionalParameters"]];
if (params[@"display"]) {
[additionalParameters setValue:params[@"display"] forKey:@"display"];
}
if (params[@"prompt"]) {
[additionalParameters setValue:params[@"prompt"] forKey:@"prompt"];
}
NSString *nonce = additionalParameters[@"nonce"];
[additionalParameters removeObjectForKey: @"nonce"];
OIDAuthorizationRequest *request =
[[OIDAuthorizationRequest alloc]
initWithConfiguration: configuration
clientId: params[@"clientId"]
clientSecret:nil
scope: params[@"scope"]
redirectURL: [NSURL URLWithString:params[@"redirectUri"]]
responseType: params[@"responseType"]
state: params[@"state"]
nonce: nonce
codeVerifier: nil
codeChallenge: nil
codeChallengeMethod: nil
additionalParameters: additionalParameters];
_currentAuthorizationFlow = [OIDAuthState
authStateByPresentingAuthorizationRequest:request
presentingViewController:[[self window] rootViewController]
callback:^(OIDAuthState * _Nullable authState, NSError * _Nullable error) {
NSLog(@"%@", [[authState lastAuthorizationResponse] additionalParameters]);
if (authState) {
[self setAuthState:authState];
} else {
result([FlutterError errorWithCode:error.description message:error.description details:nil]);
[self setAuthState:nil];
}
}];
} else {
result(FlutterMethodNotImplemented);
}
}
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<NSString *, id> *)options {
NSLog(@"a| %@", [url absoluteString]);
// Sends the URL to the current authorization flow (if any) which will
// process it if it relates to an authorization response.
if ([_currentAuthorizationFlow resumeExternalUserAgentFlowWithURL:url]) {
_currentAuthorizationFlow = nil;
return YES;
}
NSLog(@"%@", [url absoluteString]);
// Your additional URL handling (if any) goes here.
return NO;
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
NSLog(@"%@", [url absoluteString]);
return [self application:application openURL:url options:@{}];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
NSLog(@"%@", [url absoluteString]);
return [self application:application openURL:url options:@{}];
}
- (void)didChangeState:(OIDAuthState *)state {
[self saveState];
}
- (void)saveState {
// for production usage consider using the OS Keychain instead
NSData *archivedAuthState = [ NSKeyedArchiver archivedDataWithRootObject:_authState];
[[NSUserDefaults standardUserDefaults] setObject:archivedAuthState
forKey:kAppAuthExampleAuthStateKey];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)loadState {
// loads OIDAuthState from NSUSerDefaults
NSData *archivedAuthState =
[[NSUserDefaults standardUserDefaults] objectForKey:kAppAuthExampleAuthStateKey];
OIDAuthState *authState = [NSKeyedUnarchiver unarchiveObjectWithData:archivedAuthState];
[self setAuthState:authState];
}
- (void)setAuthState:(nullable OIDAuthState *)authState {
if (_authState == authState) {
return;
}
_authState = authState;
_authState.stateChangeDelegate = self;
[self saveState];
}
@end
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the AppDelegate URL handlers and the _currentAuthorizationFlow setup shown in the issue, then trace whether the custom-scheme callback reaches application:openURL:options:. Compare the callback lifecycle with the AppAuth-iOS integration guidance; done means the authorization flow resumes and the Flutter result receives the outcome.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- flutter, objective-c
- Domain
- authentication, mobile-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100