Поэтому я запускаю браузер (UIWebView) в своем приложении iOS для аутентификации. Пользователь вводит имя пользователя и пароль, и запрос на аутентификацию отправляется на сервер поставщика удостоверений. Он отправляет ответ обратно в том же окне браузера. Теперь после успешной аутентификации я хочу показать первый экран приложения. Это то, что я пробовал в коде браузера UIWebview для этого

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
   NSURL *url = webView.request.URL;

   if([url.absoluteString containsString:@"DONEWITHLOGIN"]){
      // Store cookies
   }
   // ?? How do I call app delegate from here to launch first screen
   // load custom URL scheme 

}

Вот чем я сейчас занимаюсь в своем AppDelegate

- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
    CGRect screenBounds = [[UIScreen mainScreen] bounds];

#if __has_feature(objc_arc)
        self.window = [[UIWindow alloc] initWithFrame:screenBounds];
#else
        self.window = [[[UIWindow alloc] initWithFrame:screenBounds] autorelease];
#endif
    self.window.autoresizesSubviews = YES;

#if __has_feature(objc_arc)
        self.viewController = [[MainViewController alloc] init];
#else
        self.viewController = [[[MainViewController alloc] init] autorelease];
#endif

    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];

// Call Authentication Method - this will launch a webview with URL for authentication 

    return YES;
}

- (BOOL)(UIApplication *)application openURL:(NSURL *)url sourceApplication annotation:(id) annotation 
{
   // I return here once the custom URL scheme is loaded.
   // Other code 
        self.viewController = [[[MainViewController alloc] init] autorelease];
       self.window.rootViewController = self.viewController;
       [self.window makeKeyAndVisible];

    return YES;
}

Я получаю сообщение об ошибке, пытаясь представить NavigationController для ViewController, представление которого не находится в иерархии. Ошибка исходит из строки self.window.rootViewController = self.viewController.

Я использую Кордову для этого приложения.

0
yogsma 2 Мар 2015 в 18:11

2 ответа

Лучший ответ

Кажется, вы новичок в iOS, поэтому я вам немного помогу. Во-первых, вам никогда не следует возвращаться в App Delegate для сброса представлений. Вы хотите загрузить MainViewController внутри делегата приложения, как вы это делаете сейчас. Остальной код ниже!

MainViewController.m

#import "MainViewController.h"
#import "WebViewController.h"

@interface MainViewController () <WebViewControllerDelegate>

@end

@implementation MainViewController

- (void)viewDidAppear:(BOOL)animated {
  [super viewDidLoad];
  // Do any additional setup after loading the view, typically from a nib.


  if(...userHasAlreadyFilledOutProfileScreen...){
    [self showLoginScreen:NO];
  } else {
    ... show profile screen ...
  }

}

- (void)showLoginScreen:(BOOL)animated
{
  WebViewController *webViewController = [[WebViewController alloc] init];
  webViewController.delegate = self;
  [self presentViewController:webViewController animated:animated completion:^{
    NSLog(@"Web View Loaded!");
  }];
}

- (void)showFirstScreenOfApp
{
  ... code to show first screen of app ...
}

- (void)whenUserFinishesProfileScreen
{
  ...

  [self showLoginScreen:YES];

  ...

}

- (void)didReceiveMemoryWarning {
  [super didReceiveMemoryWarning];
  // Dispose of any resources that can be recreated.
}

@end

WebViewController.h

#import <UIKit/UIKit.h>

@class WebViewController;
@protocol WebViewControllerDelegate <NSObject>
@optional
- (void)showFirstScreenOfApp;
@end

@interface WebViewController : UIViewController
  @property (nonatomic, assign) id<WebViewControllerDelegate> delegate;
  @property (nonatomic, strong) UIWebView* webView;
@end

WebViewController.m

@implementation WebViewController

- (void)viewDidLoad
{
}

- (void)viewDidAppear:(BOOL)animated
{
}

- (void)didLoginCorrectly
{
  [self dismissViewControllerAnimated:YES completion:^{
    NSLog(@"Closed Login WebView");
  }];
}


- (void)viewWillDisappear:(BOOL)animated
{
  if(...didYouLoginCorrectlySoYouShouldShowFirstScreen... && [self.delegate respondsToSelector:@selector(showFirstScreenOfApp)]){
    [self.delegate showFirstScreenOfApp];
  }
}

@end

Вот что мы делаем

  1. Загрузите MainViewContoller в AppDelegate
  2. Проверьте, заполнили ли они профиль. Если это так, сначала покажите экран входа в систему без анимации, чтобы он выглядел первым, что там
  3. Если они не заполнили страницу профиля ... настройте это
  4. Когда они заканчивают страницу профиля, мы устанавливаем делегата в MainViewController и отображаем страницу входа в систему.
  5. Когда пользователь входит в систему правильно, он закрывает Login WebViewController.
  6. Прежде чем представление исчезнет, ​​оно проверяет, правильно ли вы вошли в систему, и, если да, сообщает делегату показать первый экран приложения, к которому имеет доступ зарегистрированный пользователь.

Весь код между "..." - это то, что вам нужно заполнить, потому что я не могу вам с этим помочь :)

Надеюсь, это поможет ... НАСЛАЖДАЙТЕСЬ!

1
jkanter 7 Мар 2015 в 06:41

Я бы решил это наоборот. Ваш MainViewController - это главный экран приложения. Если пользователь не вошел в систему, он представляет собой модальное представление с окном входа в систему. После завершения входа в систему модальное представление закрывается и сохраняет учетные данные соответствующим образом, чтобы остальная часть приложения могла работать.

1
Rick 5 Мар 2015 в 19:42