gpt4 book ai didi

objective-c - 无法从 Settings.bundle 读取值

转载 作者:太空狗 更新时间:2023-10-30 03:32:34 31 4
gpt4 key购买 nike

我被动地使用这个网站已经有一段时间了,并且已经阅读了常见问题解答,所以我希望能够将这些内容保持在最低限度。

我对 Objective-C 中的 Settings.bundle 文件有疑问。我一直在使用以下指南来实现其中之一:

  • How to create an iPhone preferences file
  • iOS Application Programming Guide - Implementing Application Preferences
  • 我同时使用 Xcode 4.1 和最新的 Xcode 3。我使用版本 3 创建 Settings.bundle 及其 plist,因为我发现 Xcode 4 的 plist 编辑器有些问题。

    这些是我的 Root.plist 的内容:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    <key>StringsTable</key>
    <string>Root</string>
    <key>PreferenceSpecifiers</key>
    <array>
    <dict>
    <key>Type</key>
    <string>PSGroupSpecifier</string>
    <key>Title</key>
    <string>Authentication</string>
    </dict>
    <dict>
    <key>Type</key>
    <string>PSTextFieldSpecifier</string>
    <key>Title</key>
    <string>User ID</string>
    <key>Key</key>
    <string>user_id_key</string>
    <key>DefaultValue</key>
    <string>1234</string>
    <key>IsSecure</key>
    <false/>
    <key>KeyboardType</key>
    <string>Alphabet</string>
    <key>AutocapitalizationType</key>
    <string>None</string>
    <key>AutocorrectionType</key>
    <string>No</string>
    </dict>
    </array>
    </dict>
    </plist>

    我可以毫无问题地访问 iOS 设置菜单中的设置,还可以更改我目前拥有的单个条目的值。该值在 iOS 模拟器和我的物理 iOS 设备(iPhone 4)上的 session 之间存储。

    不过,我似乎无法从我的代码中访问此值。让我向您展示我是如何尝试实现它的(在我的应用程序的 ViewController.m 中):

    - (void)viewDidLoad
    {
    [super viewDidLoad];

    myDefaults = [NSUserDefaults standardUserDefaults];

    // DEBUG
    userID = [myDefaults stringForKey:@"user_id_key"];
    // userID = [NSString stringWithString:@"1234"];

    // DEBUG
    jsonBackendURL = @"http://example.com/jsonBackend.php";
    passphrase = @"secretPassphrase";

    theURLConnectionController = [[URLConnectionController alloc] initWithCallerObject:self];
    [theURLConnectionController getConnectionAndUpdate:NO];
    }

    奇怪的是,当我尝试在 Xcode 3 中运行该应用程序时,我既没有收到任何错误消息(如 SIGABRT 等),也没有收到任何调试器输出。 iPhone 模拟器的屏幕在尝试启动应用程序时变黑了一会儿,然后我被带回了主屏幕。

    Xcode 4 表现出一些相当奇怪的行为。它设法显示我的应用程序的用户界面一两秒钟,然后将我带回 iPhone 模拟器的主屏幕。它还在我尝试从 JSON 响应中获取值的代码中以某种方式指示 SIGABRT:

    NSString *arrivalToday = [NSString stringWithString:[jsonResponse objectForKey:@"from"]];

    由于 JSON 字符串是由 PHP 脚本使用我的应用程序传入的 GET 参数生成的(其中之一是来自 Settings.bundle 的用户 ID),所以这不起作用也就不足为奇了。但是它不应该崩溃,因为我在我的代码中早些时候发现了这个错误,但这可能与我的设置问题无关。一个真正令人头疼的问题是 Xcode(某种程度上)与我在 iPhone 模拟器中的应用程序一起崩溃。首先,Xcode 保持正常工作,除了我无法中止似乎仍在运行的程序这一事实。我可以单击 Xcode 中的停止按钮,但没有任何效果。当我尝试退出 Xcode 时,它​​询问我是否应该终止正在运行的程序,当我单击"is"时,它真的崩溃了,我不得不强制退出它。

    幸运的是,Xcode 4 为我提供了我的应用程序的调用堆栈:

    2011-07-21 11:41:04.539 OneClickCheckIn[2098:b303] http://example.com/json.php?user=(null)&pass=secretPassphrase&getStartToday
    2011-07-21 11:41:04.888 OneClickCheckIn[2098:b303] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSPlaceholderString initWithString:]: nil argument'
    *** Call stack at first throw:
    (
    0 CoreFoundation 0x00de25a9 __exceptionPreprocess + 185
    1 libobjc.A.dylib 0x00f36313 objc_exception_throw + 44
    2 CoreFoundation 0x00d9aef8 +[NSException raise:format:arguments:] + 136
    3 CoreFoundation 0x00d9ae6a +[NSException raise:format:] + 58
    4 Foundation 0x007ca14c -[NSPlaceholderString initWithString:] + 105
    5 Foundation 0x007d3266 +[NSString stringWithString:] + 72
    6 OneClickCheckIn 0x00002b5c -[OneClickCheckInViewController updateInterfaceWithJsonResponse:] + 172
    7 OneClickCheckIn 0x0000e82c -[URLConnectionControllerDelegate connectionDidFinishLoading:] + 364
    8 Foundation 0x007de112 -[NSURLConnection(NSURLConnectionReallyInternal) sendDidFinishLoading] + 108
    9 Foundation 0x007de06b _NSURLConnectionDidFinishLoading + 133
    10 CFNetwork 0x030fa48e _ZN19URLConnectionClient23_clientDidFinishLoadingEPNS_26ClientConnectionEventQueueE + 220
    11 CFNetwork 0x031c56e1 _ZN19URLConnectionClient26ClientConnectionEventQueue33processAllEventsAndConsumePayloadEP20XConnectionEventInfoI12XClientEvent18XClientEventParamsEl + 293
    12 CFNetwork 0x031c59cf _ZN19URLConnectionClient26ClientConnectionEventQueue33processAllEventsAndConsumePayloadEP20XConnectionEventInfoI12XClientEvent18XClientEventParamsEl + 1043
    13 CFNetwork 0x030f0c80 _ZN19URLConnectionClient13processEventsEv + 100
    14 CFNetwork 0x030f0acf _ZN17MultiplexerSource7performEv + 251
    15 CoreFoundation 0x00dc38ff __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
    16 CoreFoundation 0x00d2188b __CFRunLoopDoSources0 + 571
    17 CoreFoundation 0x00d20d86 __CFRunLoopRun + 470
    18 CoreFoundation 0x00d20840 CFRunLoopRunSpecific + 208
    19 CoreFoundation 0x00d20761 CFRunLoopRunInMode + 97
    20 GraphicsServices 0x0101a1c4 GSEventRunModal + 217
    21 GraphicsServices 0x0101a289 GSEventRun + 115
    22 UIKit 0x00042c93 UIApplicationMain + 1160
    23 OneClickCheckIn 0x00002609 main + 121
    24 OneClickCheckIn 0x00002585 start + 53
    25 ??? 0x00000001 0x0 + 1
    )
    terminate called throwing an exception(lldb)

    这就是我现在想到的所有相关信息。我在 Google 上进行了广泛的研究,也阅读了该网站上的一些主题,但找不到解决方案。

    最佳答案

    我终于能够解决它,很大程度上要感谢上面提到的指南:Adding a settings bundle to an iPhone App .

    上面写着:

    [...] it is important to understand that until the user actually changes the value of the setting nothing is actually set. If you check for the setting in your application it will actually return nil unless you set a default value. To do that add the following to the applicationDidFinishLaunching (or didFinishLaunchingWithOptions) method:

    // Set the application defaults
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:@"YES" forKey:@"enableRotation"];
    [defaults registerDefaults:appDefaults];
    [defaults synchronize];

    我没有意识到这一点。此外,在我看来,NSDictionary 中的值必须以某种形式初始化,否则用户以后的更改也不会生效(我一直在寻找时一次又一次地尝试更改 iPhone 模拟器中的值寻求解决方案,但没有奏效)。不过这可能只会影响 iPhone 模拟器,我还没有机会在我的物理设备上测试它。我的初始化代码现在看起来像这样(在 AppDelegate 中):

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
    // Override point for customization after application launch.
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys:
    @"1234", @"user_id_key",
    @"http://example.com/json.php", @"json_url_key",
    @"secretPassphrase", @"passphrase_key",
    nil];

    [defaults registerDefaults:appDefaults];
    [defaults synchronize];

    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
    }

    使用该代码,我可以稍后在我的代码中轻松访问 NSUserDefaults 值:

    - (void) reloadPreferences {
    myDefaults = [NSUserDefaults standardUserDefaults];

    userID = [myDefaults objectForKey:@"user_id_key"];
    jsonBackendURL = [myDefaults objectForKey:@"json_url_key"];
    passphrase = [myDefaults objectForKey:@"passphrase_key"];
    }

    我还花了一些时间寻找有关 NSDictionary 的键值对顺序的错误,直到我意识到在定义中值首先出现,然后是键。来自 Perl 背景,这对我来说有点陌生,因此如果您从 NSUserDefaults 对象获取 nil 值,可能需要注意这一点。

    这花了我大约三天的时间来修复,所以我希望这个解决方案可能对某些人派上用场。 :-)

    关于objective-c - 无法从 Settings.bundle 读取值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6774491/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com