0

好的,所以我一直在尝试在 xcode 中为钛编写一个简单的钥匙串模块,但我仍然无法正确完成。当我在 xcode 中运行程序时,它说构建成功但没有打开模拟器来运行它。我开始注释掉代码以查看导致问题的方法,当我注释掉这两种方法时模拟器运行良好。我是 Objective c 和编写模块的新手,所以任何建议都会很棒。我的主要问题是你能看出这两种方法有什么问题吗?非常感谢任何输入或建议。

+ (BOOL)setString:(NSString *)string forKey:(NSString *)key {
if (string == nil || key == nil) {
    return NO;
}

key = [NSString stringWithFormat:@"%@ - %@", [Keychain appName], key];

// First check if it already exists, by creating a search dictionary and requesting     that 
// nothing be returned, and performing the search anyway.
NSMutableDictionary *existsQueryDictionary = [NSMutableDictionary dictionary];

NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];

[existsQueryDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];

// Add the keys to the search dict
[existsQueryDictionary setObject:@"service" forKey:(id)kSecAttrService];
[existsQueryDictionary setObject:key forKey:(id)kSecAttrAccount];

OSStatus res = SecItemCopyMatching((CFDictionaryRef)existsQueryDictionary, NULL);
if (res == errSecItemNotFound) {
    if (string != nil) {
        NSMutableDictionary *addDict = existsQueryDictionary;
        [addDict setObject:data forKey:(id)kSecValueData];

        res = SecItemAdd((CFDictionaryRef)addDict, NULL);
        NSAssert1(res == errSecSuccess, @"Recieved %d from SecItemAdd!", res);
    }
} else if (res == errSecSuccess) {
    // Modify an existing one
    // Actually pull it now of the keychain at this point.
    NSDictionary *attributeDict = [NSDictionary dictionaryWithObject:data forKey:(id)kSecValueData];

    res = SecItemUpdate((CFDictionaryRef)existsQueryDictionary, (CFDictionaryRef)attributeDict);
    NSAssert1(res == errSecSuccess, @"SecItemUpdated returned %d!", res);

} else {
    NSAssert1(NO, @"Received %d from SecItemCopyMatching!", res);
}

return YES;

}

+ (NSString *)getStringForKey:(NSString *)key {

key = [NSString stringWithFormat:@"%@ - %@", [Keychain appName], key];

NSMutableDictionary *existsQueryDictionary = [NSMutableDictionary dictionary];

[existsQueryDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];

// Add the keys to the search dict
[existsQueryDictionary setObject:@"service" forKey:(id)kSecAttrService];
[existsQueryDictionary setObject:key forKey:(id)kSecAttrAccount];

// We want the data back!
NSData *data = nil;

[existsQueryDictionary setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];

OSStatus res = SecItemCopyMatching((CFDictionaryRef)existsQueryDictionary, (CFTypeRef *)&data);
[data autorelease];
if (res == errSecSuccess) {
    NSString *string = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
    return string;
} else {
    NSAssert1(res == errSecItemNotFound, @"SecItemCopyMatching returned %d!", res);
}       

return nil;
}
4

1 回答 1

1

你从哪里调用这些方法?它们在您的主模块中吗?如果您可以向我展示您希望最终 JavaScript 调用的样子,我可以更有信心地解决您的问题。

我看到的一个直接问题是您不能将原始类型(例如 BOOL)发送回 Titanium。您需要先将其转换为数字。(不要害怕,JavaScript 和它的真值仍然可以像使用 BOOL 一样使用它!)有一个宏可以帮助你过去——返回一个 NSNumber*,并像这样包装你的实际返回:return NUMBOOL(YES); 或返回 NUMBOOL(NO);。

另一个可能是你的论点。Kroll 将使用单个参数调用您的方法,您可以从中检索提供给您的参数。如果暴露给 JavaScript,您的方法签名通常如下所示: -(void)mySpecialMethod:(id)args;

第三个问题可能是您的方法的名称。“get”和“set”是 Kroll 的特殊关键字,用于属性。在您的 JavaScript 中,您将编写 myModule.property = 'something',然后在您的 Objective-c 中调用 -(void)setProperty:(id)args。

最后,我不确定您为什么将这些声明为类级别方法,而不是对象级别方法。也许如果你能解释更多关于这些方法的用途,我可以看到你正在尝试做什么并帮助你到达那里。

除此之外,您应该查看Titanium Mobile 的核心源代码,以了解更多关于在您自己的模块中使用 Objective-c 可以做什么和不能做什么。

希望这可以帮助!-道森

于 2011-08-10T04:58:29.767 回答