2

免责声明:我是 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)当应用程序已经启动但在后台并且用户通过网页上的 url 再次打开应用程序(使用不同的查询字符串)时,我在 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;
}

提前致谢!

4

2 回答 2

1

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

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

编辑:添加到重复问题的链接以获得良好的衡量标准:如何从我的 appDelegate 访问我的 viewController?iOS

于 2012-04-04T19:32:48.363 回答
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
于 2012-04-04T18:48:47.400 回答