开发者

Titanium module in objective C question

开发者 https://www.devze.com 2023-03-26 03:15 出处:网络
Ok so i have been trying to write a simple keychain module for titanium in xcode for sometime now and still i am unable to get it right. when i run the program in xcode it says build succeeded but doe

Ok so i have been trying to write a simple keychain module for titanium in xcode for sometime now and still i am unable to get it right. when i run the program in xcode it says build succeeded but does not open the emulator to run it. i started commenting out code to see which methods were causing problems and the emulator runs fine when i comment out these two methods. i am new to objective c and writing modules so any advice would be great. My main question is can you see anything wrong with these two methods. Any input or advice is greatly appreciated.

+ (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;
}


Where are you calling these methods from? Are they in your main module? If you can show me what you want your final JavaScript calls to look like, I can address your problem with more confidence.

One immediate problem that I see is that you can't send primitive types (BOOL, for instance) back to Titanium. You need to convert it to a number first. (Fear not, JavaScript and its truthy values can still use it like a BOOL!) There's a macro to help you past that -- return a NSNumber*, and wrap your actual returns like this: return NUMBOOL(YES); or return NUMBOOL(NO);.

Another could be your arguments. Kroll is going to call your methods with a single argument, from which you can retrieve the arguments that were given to you. Your method signatures will normally look like this, if exposed to JavaScript: -(void)mySpecialMethod:(id)args;

A third issue could be the name of your methods. "get" and "set" are special keywords to Kroll, and are used on properties. From your JavaScript you would write myModule.property = 'something', which then calls -(void)setProperty:(id)args in your objective-c.

Finally, I'm not sure why you have these declared as class level methods, vs object level methods. Perhaps if you can explain more about where these methods are being used, I can see what you are trying to do and help you get there.

Past that, you should take a look at the core source code for Titanium Mobile to learn more about what you can and cannot do with your objective-c in your own modules.

Hope this helps! -Dawson

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号