Laggy presentation of SLServiceTypeFacebook - ios

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.

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.

MFMessageComposeViewController - how can I find out when this has been fully presented?

The Problem - Preparing and showing an MFMessageComposeViewController is trivial as per the Apple docs. What I need to know is when this has been fully presented.
Explanation - Showing the MFMessageViewComposeController with a completion block is easy, but doesn't solve my problem:
[self presentViewController:messageController animated:YES completion:^(void){
//Controller has been shown. But not really....
}];
The problem is more obvious for messages to larger groups of recipients (say 50 people). The completion block gets called, but the phone's screen remains black. Several seconds later, the messaging window appears. Several seconds later, the recipient list becomes active with a flashing cursor. Basically, there's a lot of loading and processing that goes on after the controller has supposedly been presented.
What I'd like - To figure out when the interface has been fully loaded. I don't expect a simple answer, and I've already spent quite a bit of time on it - definitely bounty worthy. If you can post a working answer with code I'll award maximum bounty for it.
Just check MFMailComposeViewController view's frame. Once it achieves top of the screen handle the appearance.
[self presentViewController:messageController animated:YES completion:^
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^
{
while(messageController.view.frame.origin.y > 0)
{
}
dispatch_async(dispatch_get_main_queue(), ^
{
// Handle appearance of MFMailComposeViewController
});
});
}];
The other way is to wait 0.3 seconds using dispatch_after() method. But this time interval could be changed next versions of iOS.

UIImagePickerController shows last picture taken instead of camera input

I'm having a strange behaviour within my app.
For taking pictures i'm using the following pretty standard code for displaying the UIImagePickerController:
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = NO;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker animated:YES completion:nil];
It works perfectly fine the first time I tap the button which calls this action. The strange behaviour starts when I tap that button again. The UIImagePickerController starts again BUT it doesnt show the input from the camera anymore. It shows the last picture I've taken.
More Details of this state:
Tapping on the image shows the yellow square of the auto focus. (which it actually uses to focus the camera correctly)
When I tap on the ImageCapture button -> the correct image is taken and presented on the screen.
If I take a picture and press 'Retake' the regular camera image is presented as input.
More weirdness: It has nothing to do with the iPad I'm using. Creating a new example app which only has button which calls the code from above everything works perfectly fine.
I assume it has something to do with the configuration of the app. Therefore I checked everything but could not find any differences which may cause this issue.
Thanks in advance for any advice!
Update:
I do implement the UIImagePickerControllerDelegate in order to dismiss the UIImagePickerController.
In reading the Apple documentation on UIImagePickerController doc here it states that "When the user taps a button to pick a newly-captured or saved image or movie, or cancels the operation, dismiss the image picker using your delegate object. For newly-captured media, your delegate can then save it to the Camera Roll on the device. For previously-saved media, your delegate can then use the image data according to the purpose of your app." Maybe you need to implement the UIImagePickerContriollerDelegate protocol methods and properly dismiss the existing UIImagePickerController object. See UIImagePickerControllerDelegate
I finally did find the issue: It was a category on UIViewController I used somewhere else in the project. As soon as I compiled it with my project, the UIImagePickerController acted weird. So I think I somehow managed to use a method name which is also used internally by UIImagePickerController. It still confuses me a little since the category wasn't used on the UIImagePickerController at all.

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.

UIImagePickerController appears but camera doesn't start on iOS 5

I have an app where I present a UIImagePickerController with source type UIImagePickerControllerSourceTypeCamera. Everything works fine unless I leave the app and come back (multitasking is enabled so the app comes back right where it left off) and I present the UIImagePickerController again. It appears on screen but the camera never shows, the animation where the camera is revealed never happens, here is a screenshot:
If I press cancel and present the UIImagePickerController again, the camera will show up fine. So the only time this problem occurs is the first time I present the UIImagePickerController after coming back to the app. Anyone know why this is happening? I'm coding for iOS 5
I'm presenting the UIImagePickerController with:
[self presentViewController:capturePhotoPicker animated:YES completion:nil];
and dismissing it with:
[self dismissViewControllerAnimated:YES completion:nil];
I am using the same UIImagePickerController object each time I present it
I had exactly the same problem and then realized I wasn't releasing the UIImagePickerController after presenting it. The camera now works fine first-time after leaving and returning to the app.
So this is my exact code:
UIImagePickerController *takePhotoController = [[UIImagePickerController alloc] init];
takePhotoController.sourceType = UIImagePickerControllerSourceTypeCamera;
takePhotoController.delegate = self;
[self presentModalViewController:takePhotoController animated:YES];
[takePhotoController release];
It's one of those problems you can spend ages on, and the solution is not that obvious (well, it wasn't to me), so I hope this helps some people!
if you change the -(void)viewDidLoad to - (void)viewDidAppear:(BOOL)animated it fixes the problem. I've spent the last 2 weeks trying to figure this out

Resources