ObjectiveC <Custom UI> Share Extension Cancel button - ios

this could be something silly but I have this Share NSExtension implemented for my app which is holding custom UI built in MainInterface.storyboard (image attached). Now the question is, how do I back out of it?
I've tried:
[self.navigationController popViewControllerAnimated:YES];
[self dismissViewControllerAnimated:YES completion:nil];
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
..but it does not work;
The only way I got it to exit is:
#throw #""; (which I don't even think will pass Apple's submission validation..)
What am I missing?
Thanks.

With extensions you need to tell the system that you're finished.
It will be something like:
[self.extensionContext completeRequestReturningItems:nil completionHandler:nil];

Related

Sharing UIImage to UIActivityViewController Twitter/Facebook very slow to show dialog

I have an image I took from the camera and saved to the /tmp folder.
When I add this image to the activityItems of an UIActivityViewController, and then press to share with either Twitter or Facebook, I have to wait up to 20 seconds for the share dialog to appear.
Note that I'm referring to the actual "Post" dialog that appears for Twitter/Facebook, not the native share popup that spawns it.
When I share the same image from the Photos app, it appears instantly.
At first I was thinking the Photos app was resizing the image, as a smaller image appears more quickly, but than I discovered that when I share the same image directly to Twitter or Facebook with SLComposeViewController, it appears (almost) instantly.
Assuming it's something I'm doing incorrectly in code, here is what results in the glacially slow dialog appearance:
NSArray *items = #[#"foo", [UIImage imageWithContentsOfFile:#"valid path to test image"]];
UIActivityViewController *vc = [[UIActivityViewController alloc]
initWithActivityItems:items applicationActivities:nil];
[self presentViewController:vc animated:YES completion:nil];
Here's what works almost instantly:
SLComposeViewController *controller = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
[controller setInitialText:#"foo"];
[controller addImage:[UIImage imageWithContentsOfFile:#"valid path to test image"]];
[self presentViewController:controller animated:YES completion:Nil];
For what it's worth, I've also tried excluding the other share types (I read that in the past AirDrop caused issues), as well as wrapping the block to ensure I was executing on the main thread.
I assume I'm doing something wrong?
If I'm not, and these two other methods are in fact resizing the image, is there some documentation I'm missing that provides guidance as to how much resizing to do?
** Edit: additional testing seems to show this problem is unique to iOS8, as I did not experience it on an older iOS7 device.
Thanks
We've seen 4–20 seconds delay before the share dialog appear as well!.
I've fixed it by creating custom UIActivity items for Twitter and Facebook which simply calls SLComposeViewController inside performActivity method.
Seems much faster.

Dismiss View controller and present another one with one button

I have found several questions on this but haven't really seen a great answer as to how to do it other then using a delegate. I came up with a solution that works quite nicely however I'm not sure if it would be bad in the long run.
Here is my solution which thus far has performed fantastically. If anyone can tell me why this would be a bad way to implement this please let me know!
[self dismissViewControllerAnimated:NO completion:^(){
[[[[UIApplication sharedApplication] keyWindow] rootViewController] presentViewController:vc animated:NO completion:nil];
}];
That's the proper way to do this. In fact Apple introduced the completion blocks since iOS 5.0 especially for this kind of purposes.
Why would you want another way if the current way is simple and makes total sense?

iOS: idleTimerDisabled = YES works only until ImagePicker was used

I have an iPad survey tool as an internal enterprise application. I prevent screen locking with setting [[UIApplication sharedApplication] setIdleTimerDisabled: YES]; at didFinishLaunchingWithOptions of the application delegate.
That works fine until I use the imagePicker to take an image. After that, the idleTimer is activated again. I have tried to disable it after the image was taken but that doesn't work.
Here I found the hint that setting the required device capabilities in the info.plist could help. But so far it didn't. I have just added all camera specific flags.
Any ideas?
Many thanks!
Marcus
I was able to reset the UIApplication idleTimerDisabled like so:
- (void)resetIdleTimerDisabled
{
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
}
#pragma mark - UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[self dismissViewControllerAnimated:YES completion:^{
[self performSelector:#selector(resetIdleTimerDisabled) withObject:nil afterDelay:1.0];
}];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[self dismissViewControllerAnimated:YES completion:^{
[self performSelector:#selector(resetIdleTimerDisabled) withObject:nil afterDelay:1.0];
}];
}
What I suspect is happening is that internally UIImagePickerController sets UIApplication.idleTimerDisabled to YES to keep the camera from sleeping. When finished (after the delegate methods are called and apparently even after the animation completion block is executed), the UIImagePickerController sets UIApplication.idleTimerDisabled back to NO. Instead, it only should do this if the value was previously NO.
I filed a bug report with Apple. See UIImageViewControllerBug sample project.
Jamie's solution looks good! I'm just not a big fan of afterDelay: methods:)
The issue is in the PhotoLibrary framework: it disables the idleTimer prior to starting preview stream from camera and enables it again when tearing it down regardless of the previous value.
If you feel more adventures and want solution that works throughout the app, here is one involving swizzling: https://gist.github.com/zats/1a4aece697075478b44a
Tested for both cases when idleTimer disabled or enabled prior to showing image picker. My solution does not observe idleTimerDisabled while image picker is presented.
P.S. the same issue happens when using dictation feature (bug in UIDictationController)
(#jamie-mcdaniel if you would be so kind to update your bug report)

Laggy presentation of SLServiceTypeFacebook

so I'm making a post to Facebook and want the user to select an image before doing that.
Once the image is picked and I show Facebook. Problem is, when I show Facebook straight away, without the image picking part, it looks fine. When I show it after picking the image, Facebook sharing appears animated, but laggy. As if the action has a very low framerate or something.
Here's my code:
self.portraitPicker = [[UIImagePickerController alloc] init];
#if !(TARGET_IPHONE_SIMULATOR)
self.portraitPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
#endif
[self.portraitPicker setDelegate:self];
self.portraitPicker.allowsEditing = YES;
[self presentViewController:self.portraitPicker animated:YES completion:nil];
Now when this is complete, I show the Facebook posting modally:
[picker dismissViewControllerAnimated:YES completion:^{
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook])
{
self.facebookController = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
[self.facebookController setInitialText:#"Some text"];
[facebookController addImage:pickedImage];
[self presentViewController:self.facebookController animated:NO completion:nil];
}
}];
I can do this in the didFinishPickingMediaWithInfo or the imagePickerControllerDidCancel, doesn't matter, the problem still comes up.
Being desperate, I tried:
Showing it on the main thread delayed
Showing it async
Showing it outside the dismiss-block
Showing it from the AppDelegate's rootviewcontroller instead
This is not Facebook-related as it happens with SLServiceTypeTwitter as well as with MFMessageComposeViewController.
Can't seem to do away with the laggy animation that ONLY happens showing the image picker. Does anyone know what's causing this?
Given the lack of response and similar issues, I figured the cause was my own architecture.
It turns out that one of my viewcontrollers' ViewDidAppear was called after the camera picker was displayed (as it became the active viewcontroller and consequently the inactive one, giving control back to the original viewcontroller).
Blocking the background calls and animation that happened in this viewDidAppear resolved the issue. I still don't know why calling it delayed (i.e. 10 seconds, or even 100 seconds into the future, when nothing was going on) still had the laggy appearence show up, but there it is.

iOS 5: Twitter composer view appears slowly

I have a question about presenting the TWTweetComposerViewController as a modal view in iOS 5.
I use the apple sample code as below to implement a tweet method in my app.
-(void)tweet
{
//Using tweeting example code.
//Setup the build-in twitter composer view controller
TWTweetComposeViewController *tweetViewController = [[TWTweetComposeViewController alloc]init];
//Add url
[tweetViewController addURL:[self URL]];
[tweetViewController setInitialText:#""];
//Present Composer
[self presentModalViewController:tweetViewController animated:YES];
//Creat the completion handler
[tweetViewController setCompletionHandler:^(TWTweetComposeViewControllerResult result)
{
//Do something here.
[self dismissModalViewControllerAnimated:YES];
}];
[tweetViewController release];
}
This works fine, when I call the tweet method, the tweet controller does appear as a modal view.
However, the problem is: the composer shows up very slowly. It usually takes 3-5 seconds to show the composer. Of course, this is when the app calls this method for the first time. After the first time, it shows up a little bit quicker, but still take about 1~2 seconds.
I wonder if is there something I didn't do right to make the composer view appear slowly? Is there any way to speed up the process?
Btw. the testing device is the iPhone 4.
Thanks!
Yes, there is. You can preload the class by initializing it in the background sometime before you'll ever need it. Move tweetViewController into an instance or static variable, initialize and set all of its properties. Then just show it in the tweet method.

Resources