Skip to content

application:openURL:options: not called #356

@long1eu

Description

@long1eu

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions