iPhone refreshing tabcontroller and content - iphone

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.

Related

Loading PDF into UIWebView - Anything faster?

I'm doing an application, which loads PDFs from an URL, but is there anything better then using UIWebView? Or any way of loading it page-by-page instead of loading the whole file at once?
I mean it does the job, but it takes 30seconds - 3 minutes to load a PDF on an iPhone 5 while standing NEXT to the router...
I can't imagine what would happen when I ran this code on an iPhone 4 with crappy internet...
Code which does the loading:
CatalogsWebViewController *webViewController = [[CatalogsWebViewController alloc] initWithNibName:#"CatalogsWebView" bundle:nil];
NSString *urlString = [[NSString alloc] initWithFormat:#"http://%#.s3.amazonaws.com/%#",kAmazonAWSBucketName,[catalogs objectAtIndex:indexPath.row]];
NSLog(#"%#",urlString);
webViewController.pdfRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
[self.navigationController pushViewController:webViewController animated:YES];
//Here self is webViewController, which got pushed into the navigation controller.
[self.webView loadRequest:self.pdfRequest];
Hum... it turns out, it's not due to the webView, it's cause it takes an immense time to download the file from the S3 bucket. When loading it from [NSBundle mainBundle], it does it it seconds.
As the problem comes from network connectivity, you should display a loading bar while downloading the PDF so the user understands what is going on. Then, upon download completion, save the PDF in the documents folder of your app if the user wants to reopen it later

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.

IOS application change language with custom settings screen

I developed multi language, navigation controller based application. The main menu of the application have also and settings screen at below. User can change to application language with language button pressed. I want to refresh main menu screen and also settings screen language When user changed language But i did not.
NSString *path = [[NSBundle mainBundle] pathForResource:#"nl" ofType:#"lproj"];
NSBundle *bundle = [NSBundle bundleWithPath:path];
NSString *englishWord = #"translate";
NSString *translation = [bundle localizedStringForKey:englishWord value:englishWord table:nil];
NSLog(#"%# = %#", englishWord, translation);
// nl.lproj/Localizable.strings:
"translate" = "vertaal"
Keep in mind, that Apple discourages language selection in the app. The best solution is to just localize your Views and use NSLocalizableString, and just let the language in the app follow the language of the phone's settings.
make a method (which returns a dictionary of language strings loaded from plist) in the AppDelegate.
Whenever user selects a language set the NSUserDefaults accordingly, and call that method in app delegate.
Now use this method in viewWillAppear of every controller and get the desired language dictionary and load your views.
-(NSMutableDictionary*)getCurrentLanguageDictionaryFromResource
{
NSString *defaultPath;
defaultPath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%#.plist",[self getAppCurrentSettingsLanguage]] ofType:nil];
if(languageDictionary !=nil)
{
[languageDictionary release];
languageDictionary=nil;
}
languageDictionary = [[NSMutableDictionary alloc] initWithContentsOfFile:defaultPath];
return languageDictionary;
}
You need to restart application, if you want to change language.
For this, you can use local notifications to again restart your application with proper message showing user that your application will get re-started now.
Hope this description helps you......

how do i remove coredata from iphone

You know how you can Reset the coredata store on an iPhone simulator when you've changed your entity structure?
Do I need to perform a similar process when I've created a new version of my core data store that is different from what I last ran on my iPhone? If so, how, please?
Thanks
Just for convenience, until you code a way to remove the persistent store through your app, you can just delete the app off the phone. (Hold your finger on the home screen until icons get wiggly, then click the x on your app.) Then with your phone connected to your Mac, choose Product > Run in XCode and it will reinstall your app on the phone, but with empty data directories.
For deployment, of course, you need to come up with a way to do it without deleting the app, if you will ever change your data model after deployment (assume you will). Data migration is the best option, but if all else fails delete the persistent store file. It would be preferable to prompt for the user's approval before doing that. If they have important data they can decline and maybe get the old version of your app back to view the data and migrate it by hand, or they can wait until you release version 2.0.1 that fixes your data migration bug.
Here is the routine I use to reset my App content. It erases the store and any other file stored.
- (void) resetContent
{
NSFileManager *localFileManager = [[NSFileManager alloc] init];
NSString * rootDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSURL *rootURL = [NSURL fileURLWithPath:rootDir isDirectory:YES];
NSArray *content = [localFileManager contentsOfDirectoryAtURL:rootURL includingPropertiesForKeys:nil options:NSDirectoryEnumerationSkipsSubdirectoryDescendants error:NULL];
for (NSURL *itemURL in content) {
[localFileManager removeItemAtURL:itemURL error:NULL];
}
[localFileManager release];
}
If you only want to erase the store, since you know its file name, you can refrain from enumerating the document directory content:
- (void) resetContent
{
NSFileManager *localFileManager = [[NSFileManager alloc] init];
NSString * rootDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSURL *rootURL = [NSURL fileURLWithPath:rootDir isDirectory:YES];
NSURL *storeURL = [rootURL URLByAppendingPathComponent:#"myStore.sqlite"];
[localFileManager removeItemAtURL:storeURL error:NULL];
[localFileManager release];
}
But please note that in many cases, its better to migrate your store when you change your model, rather than to delete it.
locate your app in /Users/username/Library/Application Support/iPhone Simulator/4.3.2 (iOS Version may be different) and delete the .sqlite file
You can look at the path that is being sent to the persistentStoreCoordinator on setup, and remove that file. Usually the approach I have taken is that I set up the store to auto migrate, and if that fails I delete the store and attempt one more time to create the persistentStoreCoordinator which will use the now empty path.
Don't forget you may need to repopulate anything stored in the old database.

Save history of UIWebView and reload it

I have a view with a subview of UIWebView and the view is obviously managed by a view controller. Say, I browse with this UIWebView for sometime and then navigate to a different view managed by a different view controller and then return to the UIWebView view. It will load the parent URL and not the one where I had left it. How can I load the URL where I had browsed till along with the history i.e., ability to go back to the parent URL from the URL where I had switched views. The code might help.
NSString *string = [[NSString alloc] initWithString:#"http://www.google.com"];
NSURL *url =[[NSURL alloc] initWithString:string];
NSURLRequest *aRequest = [[NSURLRequest alloc] initWithURL:url];
[webView loadRequest:aRequest];
When we come back to this web view, it will load 'url' again. But, I want it to load the url where the UIWebView was last at.
Thanks.
It is really simple. On viewWillDisappear method, save the current URL of the webView.Request, on next launch, try to see if it has value and load the one existing, otherwise, load the default "google.com". Hope this helps.