Take the 2-minute tour ×

I am trying to integrate the "Open with..." functionality.

In my AppDelegate.m I have

_fileContent = [NSString stringWithContentsOfURL:url
ViewController *vc = (ViewController*)self.window.rootViewController;
        [vc refreshUI:nil];

I am using ARC, so I only call the following in my ViewController.h and later omit the @synthesize in the .m

@property (nonatomic, retain) IBOutlet UITextView *textView;

In my ViewController.m I have the following


    if ([appDelegate openedFromURL])
        NSLog(@"[refreshUI] appDelegate openFromURL (Length: %d)", [appDelegate.fileContent length]);
        NSLog(@"Contents before: %@", [_textView text]);
        [_textView setText:appDelegate.fileContent];
        NSLog(@"Contents after: %@", [_textView text]);

When I go to open my file form another application (Dropbox), the first NSLog gives me the right length of my file. The second NSLog gives me the correct "old" contents of the UITextView and the third NSLog gives me the correct "new" contents (begin the contents of the file I "opened with..." through the dropbox app). So the data does make it to my app.

THe problem is the UITextView does not get updated. If I press any other button in the UIViewController (which causes me to switch to a different UIViewController) and then go back to "ViewController" the UITextView is updated with the correct data. Even if I add an UIButton to and set its action to only call [self refreshUI] the UITextView updates.

It just doesn't refresh on its own from the method being called from AppDelegate.

What am I doing wrong? I even tried manually redrawing the UITextView with setNeedsDisplay. But that had no effect.


share|improve this question
My first guess would be that you are calling stringWithContentsOfURL:encoding:error: on a background thread, like you should, but not calling refreshUI: on the main thread. UIKit loves throwing out calls made on a background thread. –  NJones Dec 13 '12 at 16:23
I did not consciously call stringWithContensOfURL in a background thread to avoid such a problem... does it happen on it's own? The refreshUI statement is only a couple of lines after the stringWithContensOfURL and both are in the same method. –  Casper Dec 13 '12 at 16:28
And judging by the three NSLog statements it "gets there" in time - right? Would it be a solution to save the value of _fileContent in NSUserDefaults and then use a UIApplicationWillEnterForegroundNotification to trigger refreshUI which then just reads what is in the NSUserDefaults –  Casper Dec 13 '12 at 16:53
Try wrapping the refreshUI: call in a dispatch block to the main thread like so:dispatch_async(dispatch_get_main_queue(), ^{[vc refreshUI:nil];}); If that works then it's probably a threading issue. –  NJones Dec 13 '12 at 16:54
the dispatch_async(dispatch_get_main_queue(), ^{[vc refreshUI:nil];}); had no change in behavior. –  Casper Dec 13 '12 at 16:58

2 Answers 2

up vote 1 down vote accepted

As can now be deduced from your comments. It seems that your storyboard segues are instantiating a new instance of your "ViewController" class rather than returning you to your original. The original, however, is still the app delegate's rootViewController. This leads to you messaging an instance of your view controller that is not the one currently presented. Essentially, you are changing a label that you cannot see. There are a few ways to fix this.

  • Change your segues so they take you back to the rootViewController:

It's probably the easiest, and will likely improve your efficiency. In your methods that cause a return use methods with words like pop... or dismiss.

  • Use delegation:

Add a urlLaunchDelegate to your app delegate, and at appropriate times (viewDidLoad or viewWillAppear:) have your view controller set itself as the urlLaunchDelegate.

  • Use the NSNotificationCenter

Have a notification like MyApplication_LaunchURLNotification that your view controller observes. You could add the NSURL as the object.

share|improve this answer
Thanks for all your help! I opted for the first option (pop/dismiss). –  Casper Dec 13 '12 at 20:56
@property (nonatomic, retain) IBOutlet UITextView

Needs to declare a name

@property (nonatomic, retain) IBOutlet UITextView *textView

You also need to link the textView in your IBOutlet as well.

share|improve this answer
sorry... was a typo... will edit post... I did this of course –  Casper Dec 13 '12 at 16:22
And you are sure you connected it via IBOutlet? –  mac10688 Dec 13 '12 at 16:24
yes - am sure other wise the other scenarios (i.e. refresh button) wouldn't work. –  Casper Dec 13 '12 at 16:26
Why are you using _textView and not self.textView? –  mac10688 Dec 13 '12 at 16:27
Why shouldn't I? I thought it was the same? I just tested it but self.textView has the same behavior. –  Casper Dec 13 '12 at 16:32

Your Answer


