iOS error errSecInteractionNotAllowed or –25308 on SecItemAdd - iphone

I wrote some code to test adding an item to a keychain. I am testing on iPad 4.2.1 (jailbroken). I signed the binary with ldid -S prog on iPad.
Code:
#import <Security/Security.h>
#import <Security/SecItem.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <Foundation/NSObject.h>
#import <CoreFoundation/CoreFoundation.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSKeyValueCoding.h>
int main(int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSDictionary *attributesToStore = [NSDictionary dictionaryWithObjectsAndKeys:
[#"testuser01" dataUsingEncoding:NSUTF8StringEncoding],kSecAttrAccount,
[#"test123" dataUsingEncoding:NSUTF8StringEncoding],kSecValueData,
kSecClassInternetPassword,kSecClass,
[#"www.example.com" dataUsingEncoding:NSUTF8StringEncoding],kSecAttrServer,
kCFBooleanTrue, kSecReturnPersistentRef,
[#"Sample password" dataUsingEncoding:NSUTF8StringEncoding], kSecAttrDescription,
[#"password label" dataUsingEncoding:NSUTF8StringEncoding],kSecAttrLabel, nil];
NSData *persistentRef = nil;
OSStatus result = SecItemAdd((CFDictionaryRef)attributesToStore, (CFTypeRef *)&persistentRef);
if (noErr == result)
{
NSLog(#"Added item to Keychain");
}
else {
NSLog(#"Item add failed");
NSLog(#"Result code: %d",result);
}
[pool release];
return 0;
}
The code compiles and links without any noise or warnings. But execution on the iPad throws an error -25308.
How do I troubleshoot this error?

I am pretty sure you need to set kSecClass key so the keychain knows what kind of item you are trying to add.
As a side note, I found the GenericKeychain sample code to be useful after I rewrote the init method as outlined in my answer to my question here.

The main problem with the example code is that many items are encoded as NSData objects where NSString objects should be used (kSecAttrAccount, kSecAttrLabel, kSecAttrDescription and kSecAttrServer). I'm surprised that this issue wouldn't result in an exception, although behavior on iOS may be different to Lion (where I looked at this).
It may also be that specifying kSecReturnRef instead of kSecReturnPersistentRef may be more appropriate (from the documentation, using kSecReturnPersistentRef vends "a persistent reference may be stored on disk or passed between processes"). It is a way to specify a keychain item for use with SecItemUpdate, SecItemDelete or SecItemCopyMatching using it with kSecMatchItemList that has the advantage of persistence between sessions (say using NSUserDefaults) or passing to another process. If the item is only used within the lifetime of the application, or it is more appropriate to find using other attributes, then the item reference using kSecReturnRef is likely more appropriate.

Related

Internal memory in iOS simulator

I just finished the second tutorial for iOS development. When I add a new sighting, it works fine and turns up in the list of sightings. However, when I close the iOS simulator and reopen it, only the first entry is there (it is added manually). Should there be internal memory in the iOS simulator even after it is closed and reopened?
There seems to be some memory as if I add my contact info to the contacts, it is still there when I reopen it.
If so, how do I make sure that my array in the DataController file is similarly stored on the simulator/phone so it doesn't clear itself every time I reopen the simulator?
Thanks
You need to use persistent storage if you want to save data between sessions. Options include:
You can use plist files. For example if you have NSArray *array, you can save that to a plist using writeToFile:
[array writeToFile:filename atomically:YES];
You can then read this array with:
NSArray *array = [NSArray arrayWithContentsOfFile:filename];
This technique only works with standard NSString, NSNumber, etc., objects, not custom objects like BirdSighting, though.
For custom objects like BirdSighting, you could use NSKeyedArchiver and NSKeyedUnarchiver. By the way, these are not only generally useful classes for saving data for small data sets like this, but given that it features prominently in the new iOS 6 state preservation features, it's worth familiarizing yourself with this pattern.
You can use NSUserDefaults. This is really better suited for app settings and defaults, but theoretically could be used for saving data, too.
You can use CoreData. This is the preferred iOS technology for object persistence. It's a powerful and well engineered framework (though a tad complicated) and well suited if you're dealing with more significant amounts of data.
You can use SQLite, too. See this Ray Wenderlich article on using SQLite. And once you start using SQLite, you can consider using FMDB to simplify your coding effort.
If you wanted, for example, to use the second approach, NSKeyedArchiver and NSKeyedUnarchiver, the first thing is that you might want to do is make BirdSighting conform to NSCoding, by altering the #interface declaration in BirdSighting.h to say:
#interface BirdSighting : NSObject <NSCoding>
Second, you have to write the two NSCoding methods, initWithCoder and encodeWithCoder, in BirdSighting.m that define what properties can to be loaded/saved for this object:
- (NSArray *)keysForEncoding;
{
return #[#"name", #"location", #"date"];
}
- (id) initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self) {
for (NSString *key in [self keysForEncoding])
{
[self setValue:[aDecoder decodeObjectForKey:key] forKey:key];
}
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
for (NSString *key in self.keysForEncoding)
{
[aCoder encodeObject:[self valueForKey:key] forKey:key];
}
}
Your BirdSighting can now be loaded and saved with NSKeyedUnarchiver and NSKeyedArchiver, respectively.
So, focusing on the loading of the sightings, you have to (a) tell BirdSightingDataController.m what file to look for; and (b) instruct it to read that file during initialization:
- (NSString *)filename
{
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
return [docsPath stringByAppendingPathComponent:#"BirdSightings"];
}
- (void)initializeDefaultDataList
{
NSString *filename = [self filename];
self.masterBirdSightingList = nil;
if ([[NSFileManager defaultManager] fileExistsAtPath:filename])
{
self.masterBirdSightingList = [NSKeyedUnarchiver unarchiveObjectWithFile:filename];
}
if (!self.masterBirdSightingList)
{
NSMutableArray *sightingList = [[NSMutableArray alloc] init];
self.masterBirdSightingList = sightingList;
BirdSighting *sighting;
NSDate *today = [NSDate date];
sighting = [[BirdSighting alloc] initWithName:#"Pigeon" location:#"Everywhere" date:today];
[self addBirdSightingWithSighting:sighting];
}
}
The BirdSightingDataController.m can also define a method to save the data:
- (BOOL)save
{
return [NSKeyedArchiver archiveRootObject:self.masterBirdSightingList toFile:[self filename]];
}
You can now, for example, call this save method whenever you add a sighting, e.g.:
- (void)addBirdSightingWithSighting:(BirdSighting *)sighting
{
[self.masterBirdSightingList addObject:sighting];
[self save];
}
Personally, rather than saving it every time a user does any change in the app, I might rather just have my app delegate save it when the app goes into background or terminates (but that requires further changes, so I won't go into that now).
But hopefully this code illustrates how you can use NSKeyArchiver and NSKeyUnarchiver to save and load data. And clearly, for more complicated scenarios, I would generally encourage you to consider Core Data. But for small data sets, like this, this archiver pattern can be useful (and as I said, is worth being familiar with because the basic technology is also used in iOS 6 app state restoration).

Not release NSMutableString

I started developing a project in ios-5, I have created database in my application.
Here I create bdgDBArr in appDelegate that contains values like 93,55,68,95,45...
I want to create string like badge_id= #"93,55,68,95,45"
here appDelegate.sb is NSString type and sb1 is NSMutableString type
This is my code
NSMutableString *sb1 = [[NSMutableString alloc] init];
if (![appDelegate.bdgDBArr count]==0) {
for (int i=0; i < [appDelegate.bdgDBArr count]; i++) {
if (!i==0) {
[sb1 appendString:#","];
}
[sb1 appendString:[[appDelegate.bdgDBArr objectAtIndex:i] valueForKey:#"key1"]];
}
}
else {
[sb1 appendString:#""];
}
appDelegate.sb = sb1;
NSLog(#"appDelegate.sb showSB===%#",appDelegate.sb);
[sb1 release]; //error wait_fences: failed to receive reply: 10004003
sb1 = nil;
This code is working perfectly and get the output 93,55,68,45
but at the same time I got this error in NSLog
wait_fences: failed to receive reply: 10004003
Any ideas?
I can't help with your problem but you can — and should — reduce your code down to a one-liner: appDelegate.sb = [appDelegate.bdgDBArr componentsJoinedByString:#","]; which is much more expressive and does the right thing.
And while we're there:
Objective-C makes it rather easy to write code that can be read like prose. Don't break that by using member/variable names like sb or bdgDBArr.
Oh and there is an operator to test for inequality: != use that instead of negating the result of an equality test. Your future self and every other person looking at your code will be thankful.
just to try: use autorelease instead of release. does it change something?
is your property appDelegate.sb used in app delegate with a #syntetise setter/getter, or did you used your own code for the setter? in this case post your code, please.

NSMutableDictionary EXC_BAD_ACCESS

I know there are many questions about this topic but non of them work for me because mine is a little weird.
First of all I create a static singleton class. and declare a variable of NSMutableDictionary
static NSMutableDictionary* mydic
#implementation mySingleton
-(mySingleton*)getInstance
{
static mySingleton *sharedInstance;
#synchronized(self)
{
if(!sharedInstance)
{
sharedInstance = [[mySingleton alloc] init];
mydic = [[NSMutableDictionary alloc] initWithCapacity:1];
}
return sharedInstance;
}
}
-(NSMutableDictionary*)getDictionary
{
return myDic;
}
then I call this NSMutableDictionary from another class like the below.
NSMutableDictionary* singletonDictionary = [[mySingleton getInstance] getDictionary];
MyOtherClass* myclass = [singletonDictionary objectForKey:key];// Key is NSString
// Here I can see whole the values I added to myClass for that key
NSArray *checkKey = [singletonDictionary allKeys];
for(int i = 0; i < [singletonDictionary count]; i++)
{
NSLog(#"%#",[checkKey objectAtIndex:i]);// here I can see my key is there
}
[singletonDictionary removeObjectForKey:key];// here it crashes EXC_BAD_ACCESS
I am gonna get crazy about this problem. If someone has an idea please share it with me.
EDIT :
MyOtherClass * myinstance = [[MyOtherClass alloc] init];
// Fill up the instance with the desired variable here
// Forexample
// myinstance.name = [NSString stringWithFormat:#"myInstanceName"];
.
.
.
[[[mySingleton getInstance] getDictionary] setObject:myinstance forKey:key]// key is an NSString*
[myinstance release];
Thanks for help.
Omer Faruk KURT
So many problems, where to start...?
At least, it seems your getInstance method is not returning anything; it should probably return mySingleton. This could explain your EXEC_BAD_ACCESS, as singletonDictionary is probably nil as things stand.
Your singleton instantiation is wrong too - you need to check if the singleton has already been created, and return it if it has. Otherwise you can reallocate singletons, which is absurd.
Static references are poor design here, better to subclass and declare members in the header file.
This might fix your problems, but you're clearly jumping in at the deep end and you're going to encounter more trouble. I think you need to find good examples of code in texts or online and study those. If you do that pretty soon you'll learn the ropes.
The NSMutableDictionary retains objects added to the dictionary. When the objects are removed they are released. As a result, removing an object from the dictionary accesses the object. If you have previously released the object and it is dealloc'ed, then this can cause an exception to be raised. If you examine the state of the object prior to removing from the dictionary you will likely see that it has already been released and dealloced.

App crashing because of glGetString

I am running cocos2d-iphone 1.0.0 and following this tutorial to use cocos2d with ARC. Unfortunately, I am getting a 'SIGABRT' crash error whenever I try to add a TMX Tiled Map to a CCLayer. I have traced this problem down to the -(BOOL)checkForGLExtension:(NSString *)searchName, and even further to within this function to NSString *extensionsString = [NSString stringWithCString:glExtensions encoding: NSASCIIStringEncoding];
Here is the checkForGLExtension function:
- (BOOL) checkForGLExtension:(NSString *)searchName {
// For best results, extensionsNames should be stored in your renderer so that it does not
// need to be recreated on each invocation.
NSLog(#"%#", glExtensions);
NSString *extensionsString = [NSString stringWithCString:glExtensions encoding: NSASCIIStringEncoding];
NSLog(#"%#", extensionsString);
NSArray *extensionsNames = [extensionsString componentsSeparatedByString:#" "]; }
The encoding: part of NSString *extensionsString = [NSString stringWithCString:glExtensions encoding: NSASCIIStringEncoding];is probably making the application crash. I am also receiving NULL in my logs for GL_VENDOR, GL_VERSION, GL_RENDERER, and even glExtensions.
Looking back at gl.h in the OpenGLES.framework shows me this:
/* StringName */
#define GL_VENDOR 0x1F00
#define GL_RENDERER 0x1F01
#define GL_VERSION 0x1F02
#define GL_EXTENSIONS 0x1F03
In which all of them are NULL.
NOTE: I have no idea about iOS development :)
Getting NULL from glGetString usually means that the OpenGL context is not bound or was created incorrectly. You should check that. Also check for GL error with glGetError.

Objective-C memory management: BAD_ACCESS error

I'm working on a bible iPhone app. Here are the basics of what I'm doing so far:
My XMLParser parses an xml file and creates a Bible object
Specifically, the xml is stored in each Chapter object.
Once parsing is done, the viewController grabs a Chapter from the Bible and displays its innerHtml in a UIWebview.
This works, but whenever I try to access the Bible object outside of -(void)viewDidLoad; it either gives me a BAD_ACCESS error, or the results for what I'm asking for is unreadable. I think this is a memory management problem..
Here's what I'm doing in the viewController
- (void)viewDidLoad
{
[super viewDidLoad];
//Create parser and XML data object.
//Then, parse that data
finalBible = [[Bible alloc]init];
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"KJV" ofType:#"html"];
NSData *myData = [NSData dataWithContentsOfFile:filePath];
//INT I WANTED TO USE TO ITERATE WHEN BUTTON WAS PRESSED TO ADVANCE TO NXT CHAPTER
chapToShow = 2;
parser = [[XMLParser alloc] init];
nsParser = [[NSXMLParser alloc] initWithData:myData];
//set delegate for NSXMLParser
[nsParser setDelegate:parser];
//PARSE THE XML FILE AND BUILD BIBLE OBJECT - PARSED OK!!
if ([nsParser parse]) {
NSLog(#"Parsed with no errors!! :)");
}else{
NSLog(#"Error parsing document");
}
//IT SEEMS MY PROBLEMS MAY BE IN THIS TRADE OFF.
//I WANT TO STORE THE PARSER'S BIBLE IN THIS NEW BIBLE OBJECT.
finalBible = [parser getBible];
//Test querying bible via pullVerse method - IT WORKS!!
NSLog(#"%#",[finalBible pullVerse:#"65.021.000"]);
NSString *firstChap = [[[[finalBible getTestament:0]getBook:#"Genesis"]getChapterWithInt:3]getInnerHtml];
//Try and load Genesis 1 - THIS WORKS!!
NSLog(#"...Loading Genesis 1...");
[bibleView loadHTMLString:firstChap baseURL:nil];
//LOADING THE VERSION WORKS HERE!!
NSLog(#"Version = %#", [finalBible getVersion]);
}
- (IBAction)buttonPressed:(id)sender {
NSLog(#"Now reading chapter %d", chapToShow);
//HERE I'M TRYING TO GET THE BIBLE VERSION BUT THE APP CRASHES AS A RESULT
NSLog(#"Testing the bible: Version = %# \n OK", [finalBible getVersion]);
//NOTE: I've even tried [[parser getBible] getVersion] and it still doesn't work.
// I don't release the parser till the view's dealloc method, so I'm not sure why I
// can't access it here...
}
Of course, I'd be happy to post any other code. I just didn't want to over-stuff the page with code, so I pasted only where I think the problem lies, or at least where it's occurring.
You allocate finalBible, but then you set finalBible = [parser getBible] so the previous allocation is pointless. Also, it appears as though [parser getBible] returns an autoreleased object, so you should call [[parser getBible] retain] to make sure it does not leave memory.
This is exactly what you need to do in your .h file add this line:
#property(nonatomic, retain) Bible finalBible;
Then in your .m file add this line at the top:
//This generates the methods (get, set) for your instance variable
#synthesize finalBible;
Then drop this line:
finalBible = [[Bible] alloc]init];
This is because if you keep it, there will be a memory leak right here:
finalBible = [parser getBible];
Because now you are pointing to a new memory location, and the previous memory location had an object with a retain count of 1 provided by alloc init, and since there will no longer be any reference to this object it will never be released causing a memory leak.
Although if you use this line:
self.finalBible = [parser getBible];
Because that uses the setter, a setter releases the previous value and retains the new one, so there would not be a memory leak, but it would still be pointless to allocate that object.
Since getBible does not have the new, alloc or init keyword it should return an autoreleased object, which is why the object is released in the next run loop (not guaranteed but most likely), which is why you cannot access it outside of the viewDidload() method.
You can resolve this problem by making "finalBible" variable a property of the class using
#property(nonatomic, retain) Bible finalBible; //this is in the .h file
#synthesis finalBible; // at the top of .m file
All the reference to "finalBible" should be made as "self.finalBible"