当应用程序变为活动状态时,我的视图控制器中不会调用viewWillAppear

时间:2012-04-04 18:40:14

标签: ios viewcontroller

免责声明:我是iOS菜鸟。

我使用Xcode的模板创建了一个基于视图的应用程序,该模板将图片上传到网站。 Xcode自动为我创建了AppDelegate.m(& .h)和ViewController.m以及一个故事板。该应用程序是使用URL架构从网站启动的,我在视图控制器中使用该信息。我有两个问题:

1)这是将查询字符串从AppDelegate传递给视图控制器的好方法吗? 我的AppDelegate中有一个名为queryStrings的NSDictionary属性,用于存储查询字符串。然后在我的视图控制器的viewWillAppear中,我使用以下代码来访问它:

AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    NSDictionary *queryStrings = appDelegate.queryStrings;
    wtID = [queryStrings valueForKey:@"wtID"];

2)当应用程序已经启动但在后台并且用户通过网页上的网址(使用不同的查询字符串)再次打开应用程序时,我已经在AppDelegate中实现了openURL,它在AppDelegate中填充了我的queryStrings属性。问题是:从不调用视图控制器的viewWillAppear方法,因此不执行上述代码。如何将查询字符串数据提供给视图控制器?视图控制器如何知道应用程序刚刚变为活动状态?

注意:因为项目是使用Xcode中的“基于视图的应用程序”模板创建的,所以我的AppDelegate唯一的属性是window属性。我不知道在代码中我的视图控制器甚至被AppDelegate引用了......它永远不会被设置为rootViewController或代码中的任何东西......我想这只是我看不到的一些IB魔法

如果有帮助,这是我的AppDelegate.h:

#import <UIKit/UIKit.h>


@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) NSDictionary *queryStrings;

@end

这是我的didFinishLoadingWithOptions,openURL和我的帮助方法:parseQueryString:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    [[JMC sharedInstance] configureJiraConnect:@"https://cmsmech.atlassian.net/"           projectKey:@"WTUPLOAD" apiKey:@"7fc060e1-a795-4135-89c6-a7e8e64c4b13"];

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsURLKey] != nil) {
        NSURL *url = [launchOptions objectForKey: UIApplicationLaunchOptionsURLKey];
        NSLog(@"url received: %@", url);
        NSLog(@"query string: %@", [url query]);
        NSLog(@"host: %@", [url host]);
        NSLog(@"url path: %@", [url path]);
        queryStrings = [self parseQueryString:[url query]];
        NSLog(@"query dictionary: %@", queryStrings);
    }
    else {
        queryStrings = [self parseQueryString:@"wtID=nil"];
    }

    return YES;
}


-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
    NSLog(@"openURL executed");
    if (!url) 
        return NO;
    NSLog(@"query string: %@", [url query]);
    queryStrings = [self parseQueryString:[url query]];

    mainViewController.wtID = [queryStrings valueForKey:@"wtID"];
    return YES;
}

-(NSDictionary *)parseQueryString:(NSString *)query
{
    NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithCapacity:6];
    NSArray *pairs = [query componentsSeparatedByString:@"&"];
    for (NSString *pair in pairs)
    {
        NSArray *elements = [pair componentsSeparatedByString:@"="];
        NSString *key = [[elements objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSString *val = [[elements objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        [dictionary setObject:val forKey:key];
    }
    return dictionary;
}

提前致谢!

2 个答案:

答案 0 :(得分:1)

所以,故事板开始让我紧张,我甚至没有构建你的应用程序! :)

正如我在你的另一个问题中所述(其中这是重复的,但是嘿),缺少对视图控制器的引用是由于故事板。将视图添加到层​​次结构时,将调用viewDidAppear和viewWillAppear。往返于背景和前景不符合添加到层次结构的条件。幸运的是,您的应用会发送与AppDelegate中的方法相对应的通知。只需注册为UIApplicationWillEnterForegroundNotification通知的观察者。然后,您可以在接收该通知后触发的方法中更新您的UI!

编辑:添加指向重复问题的链接以获得良好衡量标准:How do I access my viewController from my appDelegate? iOS

答案 1 :(得分:0)

嗯,那么为什么UIViewController中没有声明AppDelegate

<强>更新

当您创建新项目时,您应该在AppDelegate

中使用这样的内容
@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) UIViewController *viewController;

@end

//

#import "ViewController.h"

@implementation AppDelegate

@synthesize window, viewController;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.viewController = [[ViewController alloc] init];

    [self.window setRootViewController:self.viewController];
    [self.window makeKeyAndVisible];

    return YES;
}

//...

@end