I have done test app following this tutorial
I try to do the same without using Storyboards and it isn't work. I have enabled state preservation and restoration in AppDelegate. I have assigned restorationIdentifier to all my controllers and their views. I think i have to implement some additional code in AppDelegate to restore rootviewcontroller, but i cannot find the right way to do this.
-(BOOL)application:(UIApplication *)application shouldRestoreApplicationState:(NSCoder *)coder
{
return YES;
}
-(BOOL)application:(UIApplication *)application shouldSaveApplicationState:(NSCoder *)coder
{
return YES;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
UIViewController *viewController1 = [[[StateTestFirstViewController alloc] initWithNibName:#"StateTestFirstViewController" bundle:nil] autorelease];
UIViewController *viewController2 = [[[StateTestSecondViewController alloc] initWithNibName:#"StateTestSecondViewController" bundle:nil] autorelease];
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
self.tabBarController.restorationIdentifier = #"TabBarController";
self.tabBarController.viewControllers = #[viewController1, viewController2];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
Actually, your view controllers are restored between application:willFinishLaunchingWithOptions: and application:didFinishLaunchingWithOptions: so if you change your code to:
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
UIViewController *viewController1 = [[[StateTestFirstViewController alloc] initWithNibName:#"StateTestFirstViewController" bundle:nil] autorelease];
UIViewController *viewController2 = [[[StateTestSecondViewController alloc] initWithNibName:#"StateTestSecondViewController" bundle:nil] autorelease];
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
self.tabBarController.restorationIdentifier = #"TabBarController";
self.tabBarController.viewControllers = #[viewController1, viewController2];
self.window.rootViewController = self.tabBarController;
return YES;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self.window makeKeyAndVisible];
return YES;
}
It worked for me. Also I recommend that you watch the WWDC 2012 Session 208 — Saving and Restoring Application State on iOS.
I had quite a few issues trying to implement this as well.
First of all, have you succeeded in making this work with storyboards?
Your code looks good and you shouldn't need anything else as there are only 2 requirements:
Set shouldRestoreApplicationState and shouldSaveApplicationState to YES in the AppDelegate
Set restoration ID's to All the UIViewControllers (UIViews don't need it)
I would suggest you pay attention to the way you "Kill" the App.
In the simulator :
Hit the simulator home button.
Stop the App with Xcode.
Play the App with Xcode.
Indeed, the system deletes your application state as soon as you kill the App from the multitask bar.
If you want it to work fine using the multitask bar, you have to set
"Application does not run in background" to YES in the Info.plist file.
Hope it helps ;)
Related
i am using UIActivityViewController in ios8
and using ARSafariActivity.h
NSURL *newsURL = [NSURL URLWithString:string];
NSString *newsTitle = #"..."
ARSafariActivity *safariActivity = [[ARSafariActivity alloc] init];
UIActivityViewController *avc = [[UIActivityViewController alloc]
initWithActivityItems:#[newsTitle, newsURL]
applicationActivities:#[safariActivity]];
[avc setRestorationIdentifier:#"Activity"];
[self.navigationController presentViewController:avc animated:YES completion:nil];
Everything is working properly, but when i test app in my iPhone the console show this:
LaunchServices: invalidationHandler called
How i can fix that?
Seem to be discussed/answered in several threads, e.g. here: This is a bug on Apple's side
In short - it's debug message from iOS and you should not care about it
I am developing a iPad application which always shows in Landscape mode.
in iOS5, I was using 'shouldAutorotateToInterfaceOrientation' to return the value as 'YES' and I also configured the info.plist to support only the landscape mode. All goes well.
In iOS 6, I am aware that the method 'shouldAutorotateToInterfaceOrientation' is deprecated. I went thru lot of discussions in the net and tried all suggested solutions but the results are still zero (Meaning, iOS6 simulator shows in portrait mode.
My code is given below…. Any advise is very much appreciated…
In the AppDelicate.m
MyTestUI *myTest = [[MyTestUI alloc] init];
navigationController = [[UINavigationController alloc] initWithRootViewController:myTest];
[navigationController setNavigationBarHidden:YES];
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
[myTest release];
return YES;
in the MyTestUI.m
- (BOOL)shouldAutorotate {
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (orientation == UIInterfaceOrientationPortrait) {
}
return YES;
}
**// iOS 5.1 Fix is below**
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
In AppDelegate.m
Instead of
[self.window addSubview:navigationController.view];
use this one:
[self.window setRootViewController:navigationController];
Hope this helps.
If you want your app to always be in landscape simply select landscape in the summary in xcode.
Your app is now locked to landscape
Ok, orientation since iOS 6 is handled from top to bottom :
supported orientation in the summary in XCode : if ALL your screens support the same orientation, then just use this one as it is the simplest.
If you handle different orientation rules depending on the screen of your application, then you want to use shouldAutorotate and supportedInterfaceOrientation methods for each UIViewController. (but do note that UINavigationController orientation doesn't depend on its top viewController - as opposed to what you might expect, so you could have to subclass UINavigationController to handle that correctly :
In MytestUI :
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
and in your UINavigationControllersubclass
- (BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.topViewController preferredInterfaceOrientationForPresentation];
}
BLUF: Google Analytics iOS v2 beta 4 misses tracking my first UIViewController that is loaded while hitting successfully on subsequent UIViewControllers (subclassed with GAITrackedViewController)
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
// Optional: automatically send uncaught exceptions to Google Analytics.
[GAI sharedInstance].trackUncaughtExceptions = YES;
// Optional: set Google Analytics dispatch interval to e.g. 20 seconds.
[GAI sharedInstance].dispatchInterval = 0;
// Optional: set debug to YES for extra debugging information.
[GAI sharedInstance].debug = YES;
// Create tracker instance.
[[GAI sharedInstance] trackerWithTrackingId:#"UA-########-1"]; // id<GAITracker> tracker =
return YES;
}
MainViewController.m
- (void)viewDidLoad
{
NSLog(#"viewDidLoad");
[super viewDidLoad];
self.trackedViewName = #"First Screen";
//[[GAI sharedInstance] dispatch];
...
}
I do not call dispatch manually on the working UIViewController's, and I have tried both calling and not calling on the non-working. But it is a mystery. No logs are generated if I don't call it manually. When I do call dispatch manually I receive the following:
GoogleAnalytics 2.0b4 -[GAIDispatcher initiateDispatch:retryNumber:]
(GAIDispatcher.m:481) DEBUG: No pending hits.
Thanks in advance!
Turns out that you should really make sure that if you override any methods, you should make sure to call super on them as well...
I had written my own viewDidAppear method but had not called [super viewDidAppear:animated];. I guess that is where GoogleAnalytics does their magic. Hopefully this will help someone else not do this as well.
in my Case , I did call super method , but it did not work at some pages .
and I just change the order and let GA before the super method , It did work now .
- (void)viewDidAppear:(BOOL)animated {
self.screenName = #"mainMenu";
[super viewDidAppear:animated];
}
Contrary to Shu Zhang answer: super should be called first and then you should add other code:
- (void)viewDidLoad
{
[super viewDidLoad];
self.screenName = #"YourViewControllerName";
//your implementation here
}
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
///your implementation here...
}
I cannot get social frameworks to function correctly on my ios device, however it functions perfectly in the iOS simulator but not on my iPad, can anyone advise on where I may have gone wrong. Thanks in advance.
- (IBAction)sharefb:(id)sender {
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) {
mySLComposerSheet = [[SLComposeViewController alloc] init];
mySLComposerSheet = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
[mySLComposerSheet setInitialText:#"Share this app with your friends"];
[mySLComposerSheet addImage: [UIImage imageNamed:#"icon2.png"]];
[self presentViewController: mySLComposerSheet animated:
YES completion:nil];
}
[mySLComposerSheet setCompletionHandler:^
(SLComposeViewControllerResult result) {
NSString *output = [[NSString alloc] init];
switch (result) {
case SLComposeViewControllerResultCancelled:
output = #"Post Cancelled";
break;
case SLComposeViewControllerResultDone:
output = #"Posted successfully";
break;
default:
break;
}
}];
I just copy/pasted your code into a blank project and ran it on my iPad successfully, so I'm not exactly sure what the problem is but here's a couple of things you can try.
First, you use both of these lines in your code:
mySLComposerSheet = [[SLComposeViewController alloc] init];
mySLComposerSheet = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
It is unnecessary, and unwise to call alloc/init on the composer right before composeViewControllerForServiceType which returns a SLComposeViewController object already. Omitting the first of those two lines could solve the problem.
Second, are you sure that "icon2.png" exists in the project? This shouldn't be causing the problem, but hey crazier things have happened.
Third, also unlikely but it is possible that you have some strange invisibles creating problems with the arguments of presentViewController due to your spacing and line break placement. Try rewriting the line to look like this:
[self presentViewController:mySLComposerSheet animated:YES completion:nil];
Site note, your NSString *output is creating a memory leak, unless it is used for something else that you haven't included in your code. This is all going off of your original post which does not actually specify the problem. If you can be more specific, I can probably be more helpful.
I'm struggling with file handling on iOS.
I could already assign my file type to iOS and I can launch my app from mail with a special file.
My app is launching and I'm firing this method:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
if([url isFileURL])
{
NSString *fileConts = [[NSString alloc] initWithContentsOfFile:[NSString stringWithFormat:#"%#", url] encoding:NSUTF8StringEncoding error:nil];
[self.viewController openFile:fileConts];
fileConts = nil;
}
return YES;
}
The openFile:(NSString) method is declared in the viewController and sets the value of a textView (for now). This method works fine. I tested it via [self.viewController openFile:#"test"];.
But when my application launches with file attached, the textView keeps empty.
It seems that it doesn't adopt the string value or that it can't read the string value.
handleOpenURL will be called only if application already running (in the background).
To make sure you correctly dispatch incoming files, you also need to check it on the app launch:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *url = (NSURL *)[launchOptions valueForKey:UIApplicationLaunchOptionsURLKey];
// Process url here
}
It's good idea to have 1 URL dispatcher called both from handleOpenURL and didFinishLaunchingWithOptions.
I could solve my problem.
My mistake was to initWithContentsOfFile:(NSString *)
I updated my code with
NSString *fileConts = [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
Now I'm happy!
Thanks for help.