EXC_BAD_ACCESS When NSSearchPathForDirectoriesInDomains in iOS5 - iphone

I'm developing an App that will update the UI every time a View "A" appears. I put the related code in the ViewWillAppear and this update will load some images in the document path of the app. Thus, I will load the related path in the section. And it works fine in the beginning, but if I navigate to another page (using navigationController to push page) and back to this page again several times, I will got an EXC_BAD_ACCESS.
Code:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); // EXC_BAD_ACCESS here
NSString* docPath = [paths objectAtIndex:0];
.....
And if I temporarily change the code by hardcoding the path like:
NSString* docPath = [NSString stringWithFormat:#"****/****/***/Documents"];
then it will not crash.
I also tried to load the document path at ViewDidLoad and save the value to a variable where the property is (nonatomic, retain).
And in the ViewWillAppear, I load the path like:
NSString* docPath = self.documentPath;
but it will also got an EXC_BAD_ACCESS at this line.
Before this line, I also tried to print the self.documentPath, and it will get the correct path string.

Check out my this answer to see how to debug EXC_BAD_ACCESS error and then put up the error description here. That would help to answer your question.

Related

Open pdf with other apps

I am displaying a pdf file in an app. I want to show "open with" option on nag bar showing apps installed on iPhone that can open same pdf and if user selects any of the app (for e.g. pdf viewer) then the pdf should get open with pdf viewer app.
How do I do this?
Please help
Thanks in advance.
To open a file in an available application on the device, use the UIDocumentInteractionController class.
A document interaction controller, along with a delegate object, provides in-app support for managing user interactions with files in the local system. For example, an email program might use this class to allow the user to preview attachments and open them in other apps. Use this class to present an appropriate user interface for previewing, opening, copying, or printing a specified file.
There are a lot of questions around it on SO if you get stuck. search results for UIDocumentInteractionController
This code will present the OpenIn interaction you're looking for. It works for iPhone and iPad. On iPad its in a popover. I'm generating the PDF but if you're just using one you have you don't need to writeToFile, just hand in the filePath.
// In your header. MyViewController.h
#interface MyViewController : UIViewController <UIDocumentInteractionControllerDelegate>
{
UIDocumentInteractionController *docController;
}
// In your implementation. MyViewController.m Open Results is hooked up to a button.
- (void)openResults
{
// Generate PDF Data.
NSData *pdfData = [self makePDF];
// Create a filePath for the pdf.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"Report.pdf"];
// Save the PDF. UIDocumentInteractionController has to use a physical PDF, not just the data.
[pdfData writeToFile:filePath atomically:YES];
// Open the controller.
docController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:filePath]];
docController.delegate = self;
docController.UTI = #"com.adobe.pdf";
[docController presentOpenInMenuFromBarButtonItem:shareButton animated:YES];
}
You can check with Apple Default api of "UIDocumentInteractionController".
Below is url:
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIDocumentInteractionController_class/Reference/Reference.html
Hope, it will resolve your issue.
Cheers.

iPhone refreshing tabcontroller and content

I have two problems I am trying to solve, one is refreshing the tab controller itself and the other is refreshing the content of the tabcontroller.
The reason I wish to refresh the tab controller itself is that my application has a web call which returns a JSON which sets up the order of the tabs and also sets up the content of each tab. I have got it so that when you back out of the application and reenter the application the tab controller is refreshed by putting
exit(0)
in the AppDelegates ApplicationDidEnterBackground so that when the user backs out and in again the controller will be refreshed. In the applicationDidFinishLaunchingWithOptions, I have set up a web call which calls the JSON which is then used to set up the tab order. I know this is not a good way of doing this, but for the time being, its the only solution I can think of. How else can I refresh the TabController?
As for the tab content, it is refreshed using using this code
becomeActiveObserver = [[NSNotificationCenter defaultCenter]
addObserverForName:UIApplicationDidBecomeActiveNotification
object:nil
queue: nil
usingBlock:^(NSNotification *note){
[self refresh];
[self viewDidUnload];
}];
I have set this type of code up for each of the 5 tabs. This works very well, but the problem is the content only refreshes when the application is exited and accessed again. The web call will be periodic and I would like it when the web call is made that the content will refresh itself without me having to back out and in to the application again.
For testing purposes I have set up a button in my settings screen (settings screen is just a another view within one of my tabs) that when clicked with read JSON is stored in the iPhone directory which is different from the JSON retrieved from the web call (saves me having to go to the server and keep changing the JSON there). When this button is clicked, it should read this new JSON, update the content and then refresh the view. I have tested this and the JSON is being read and the data is being updated (I set up a button on each screen which would read out the JSON it is using to confirm this) but the view is not refreshing until I exit and enter the application again.
The temp code I have set up in the settings screen to read the JSON stored on the device is
-(IBAction)RefreshApp:(id)sender{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"widgjson" ofType:#"json"];
NSData *myData = [NSData dataWithContentsOfFile:filePath];
NSString *responseString = [[NSString alloc] initWithData:myData encoding:NSUTF8StringEncoding];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex: 0];
NSString *docFile = [docDir stringByAppendingPathComponent: #"json.txt"];
[fileManager removeItemAtPath:docFile error:NULL];
[responseString writeToFile:docFile atomically:NO encoding:NSUTF8StringEncoding
DashboardVC *db = [[DashboardVC alloc] init];
[db refresh];
[db viewDidUnload];
}
At the bottom you can see I tried to call refresh from one of the tabs to refresh one of the views do see if that worked, but no luck. The refresh code only seems to work when you call it from inside the class itself, I can't seem to get it to refresh when accessing it from another class.
When a web call is made, I want every single tab to be refreshed at once. Any ideas on how I would do this?
Would be very grateful if someone could point me in the right direction.
UITabBarController's setViewControllers: animated: method is what you want to use here.
When you receive a notification where you want to re-order the tabs, use that function to pass along the various view controllers owned (and referred to) in your tab bar in an array which is in the order of how you want your tabs to appear.

App Crashing When Relaunching

When I hard exit (double click home and minus) and then relaunch app it is freezing up.
The Console shows this:
[app directory path .....]has changed; re-reading symbols.
I think it may have to do with this code in my appdelagate.m
- (void)applicationWillTerminate:(UIApplication *)application
{
[self saveCode];
}
- (void)saveCode
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"routine.plist"];
[NSArray writeToFile:path atomically:YES];
}
First: saving a plist to populate a UITableViewController is a really tedious way to save data persistently and an inconsistent one as you may have realized, I would recommend that you use Core Data instead.
Second: Run the debugger (before launching your app) and find any line of text that's shown in black (grey lines are for methods called by the os and the cocoa layer, black ones are for your own methods). The debugger can be run via Run > Debugger or Command + Shift + Y.
The similar kind of crashing issue - on quick relaunch is being faced when I use location manager in the application. The case is : my application quits on pressing home button rather than going into the background in iPhone 4. And on iPhone 3G (where no background processing is supported) the case is same - it crashes on relaunch [atleast it seems like a crash].
If we wait even 1 second to relaunch the app, it does not crash.

EXC_BAD_ACCESS on NSString,when application is brought to foreground from background [ on 4.0 OS ]

Currently My application is getting crashed on accessing NSString after bringing application to foreground from background [on 4.0 OS].
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
iDatabasePath = [documentsDirectory stringByAppendingPathComponent:KApp_DB_Name];
iDatabasePath is declared as NSString* and it is globally declared.
When Application is moved to background and brought to foreground when I make a call to
iDatabasePath = [documentsDirectory stringByAppendingPathComponent:KApp_DB_Name];
Application crashes due to EXC_BAD_ACCESS to iDatabasePath and this is happening on 4.0 OS
Please help me on this.
Thanks,
Sagar
you need to retain it...
[iDatabasePath retain] somewhere - probably applicationDidEnterBackground
so which line is the error on? If its on the line you say, it looks like documentsDirectory would be getting released, not iDatabasePath, have you tried to retain iDatabasePath?

memory leak in device not in simulator

I have checked using instruments and not found any memory leaks.
when i check in device it shows memory leaks with responsible caller -[NSKeyedUnarchiver decodeObjectForKey:] and object is UIRoundedRectButton.
I still not using NSKeyedUnarchiver or any type of decoding. Is following code, is responsible for this memory leak ?
- (void)saveToFile:(NSString *)pinStr
{
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
NSString *path = [documentsDirectoryPath stringByAppendingPathComponent:#"smsbrain.plist"];
NSMutableDictionary *data = [[NSMutableDictionary alloc] init];
[data setObject:#"User" forKey:#"username"];
[data setObject:#"password" forKey:#"password"];
[data setObject:pinStr forKey:#"pin"];
[data writeToFile:path atomically:YES];
[data release];
}
Or i have checked through internet & also some post on stackoverflow but not find any better solution.
I am not setting outlet to nil in viewdidunload & in dealloc methods. is it create any problem?
my application hides background when this leaks occur. and on console i get warning "Memory level is not normal (20 %)"
So, what to do for the problem of invisible of background of tableviewcontroller. it is working fine on simulater. but what is problem in device that it sometime hide background.
please help me...
If you are not doing any NSCoding on yourself, the responsible caller is most likely a UIViewController that is decoding it's nib file. The memory warning you receive fits into this assumption.
When a memory warning is raised the standard implementation of UIViewController will release it's view, if is not visible (doesn't have a superview). As a result all subviews of that view will receive a release message and be dealloced, if no one retains them. But normally the viewController will at least retain some of it's view subviews trough it's IBOutlet properties. This is were viewDidUnload comes into play. It's called right after the view was unloaded (mostly due to a memory warning). This is the place were you really should release all retained subview of your view. That is every IBOutlet and erverything you created in viewDidLoad. There's really no need to hold them. They will all be recreated from the nib when needed.
In your dealloc method you have to release all retained properties and all retained ivars, that do not back a property. Please read the Memory Management Programming Guide
If this doesn't help. We would need your property declarations and the viewDidLoad, viewDidUnload, dealloc methods of the Controller in question.