Repeated speech in email compose window when using Voiceover - ios

As Voiceover users attempt to dictate in an email compose window, their words are repeated back to them as they speak.
Although this does not happen in Mail, it does occur both in my complex shipped app, and in a very simple test app, which is just a default template with only this code added...
#interface ViewController () <MFMailComposeViewControllerDelegate>
-(void) viewDidAppear:(BOOL)animated {
MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init];
mailViewController.mailComposeDelegate = self;
[mailViewController setSubject:#"Subject Goes Here."];
[mailViewController setMessageBody:#"Your message goes here." isHTML:NO];
[self presentViewController:mailViewController animated:YES completion:NULL];
}
Has anyone seen this, and knows of a solution, or can confirm that it is an iOS bug? I see almost no similar reports of it around the web.
I do wonder if I am using Voiceover incorrectly, but I don't see a similar problem in Mail. Normal dictation into this window works fine (although I am seeing a stereo waveform displayed instead of the usual mono one at the moment- I'm not sure if that is relevant)

I was able to replicate the behavior, but you have to do some weird things. The only way I was able to get this to happen was by moving accessibility focus away and back into the composer view after enabling dictation. This is a bug and since it's a bug contained in a bit of private API it's a bug you can't really work around. In practice I would suspect that it's a bug that wouldn't show itself very frequently.

Related

MFMailComposeViewController iOS9 bug (on iPad mini 4)

I think there's an issue with the MFMailComposeViewController in iOS9, at least on my new iPad mini 4.
Even using the simplest test code I doesn't work. For example, using:
if(![MFMailComposeViewController canSendMail]) {
return;
}
MFMailComposeViewController *controller = [MFMailComposeViewController new];
controller.mailComposeDelegate = self;
[controller setSubject:#"Test"];
[controller setMessageBody:#"Test" isHTML:FALSE];
[self presentViewController:controller animated:TRUE completion:^{
}];
The App becomes completely unresponsive, NOTHING happens on the screen, I see no draft e-mail or something like that.
Important things to know:
YES, my device can send mail, I've used the default canSendMail check
I've tried strong-referencing the controller but it had no effect
The exact same code works perfectly on another iPad running iOS8
In the simulator it DOES show the draft but closes immediately saying that "MailCompositionService suddenly quit"
Anybody any ideas?
Ok I created a complete barebone test-App and found out it DID work there so something else was the issue. I finally discovered the issue was that the App showed a tableview with about 50 rows (I did use recycling) but that created a memory issue... (I did check with Instruments but no leaks).
Anyway, I found out if I present the mailcontroller when NOT also showing the tableview it had no issues at all.. You'd think that the iPad mini 4 would be capable of both.
So the lesson learned is, create a complete barebone test-app first before posting questions on SO..

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.

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.

UIActivityViewController: Choosing an activity for which permissions are denied leads to a dead end

I am using a UIActivityViewController to implement image sharing.
UIActivityViewController *shareVC = [[UIActivityViewController alloc] initWithActivityItems:#[image] applicationActivities:nil];
[shareVC setCompletionHandler:^(NSString *activityType, BOOL completed){
NSLog(#"completed image export activity: %# - %d", activityType, completed);
}];
[self presentViewController:shareVC animated:true completion:nil];
In testing, I have noticed that if the user selects, for example, "Assign to Contact", but then denies the permission in the ensuing dialog, then they are taken to a screen that says "This app does not have access to your contacts. You can enable access in Privacy Settings.", from which there is no way to back out. The only way for them then to get back to the actual app is to manually restart it.
I'm fairly happy to leave this behaviour as is for now since I don't anticipate any users will be particularly bothered by it, but I'd like to know if there is a sensible way to work around it, and if it is indeed the expected behaviour.
Hmm, maybe you could check if a segue is called when the new "This app does not have access to your contacts. You can..."-Viewcontroller is shown. Then you could manipulate the destinationViewController property of the segue and add for example a button, with an action enabling the user to go back.
All highly theroretical.
I am working on the iPad platform, and in that context presenting a UIActivityViewController directly is wrong according to the documentation, which states that
When presenting the view controller, you must do so using the appropriate means for the current device. On iPad, you must present the view controller in a popover. On iPhone and iPod touch, you must present it modally.
In most ways, the behaviour of the modally presented view controller on iPad seemed perfectly fine, but this case illustrates why it is not appropriate. I don't know how the equivalent case is handled on iPhone / iPod touch as I haven't really looked at those platforms just yet.
Now that I am presenting it in a UIPopoverController, the view explaining that the app doesn't have access to contacts appears within the popup, and is dismissed as the popup is dismissed. Unfortunately it appears that the completion handler is not called in this case; I'm not sure if that's an iOS bug or if I lack understanding of something. It is a slight problem for me at the moment, so I'll have to work around it.
Unfortunately, it seems relatively unlikely that anyone experiencing a related problem will be helped by my question / answer; maybe I'll try to edit the question.

UIDocumentInteractionController for Open In menu - Doesn't Work

I implemented a UIDocumentInteractionController to send files to other apps. The file is a .txt file.
Here's the code:
UIDocumentInteractionController *interactionController = [[UIDocumentInteractionController alloc] init];
[interactionController setURL:[NSURL fileURLWithPath:filePath]];
[interactionController setUTI:#"public.text"];
[interactionController setDelegate:self];
[interactionController presentOpenInMenuFromBarButtonItem:actionBarButtonItem animated:YES];
The menu opens fine, showing apps like Pages, Dropbox, etc. as I expect. But when I tap one of them, the Open In menu dismisses and no action is performed (the file is not sent and the target application never opens.
I tried implementing the delegate methods documentInteractionController:canPerformAction: and documentInteractionController:performAction: for triggering copy: and print: calls using the options menu (as opposed to the open in menu) and that pulled up a menu with only Pages listed, but that still did not work.
How might this be resolved?
I found the answer, and it's memory management. I create the UIDocumentInteractionController and then present it, but I don't have it as an instance variable. ARC deallocates it before it has the opportunity to do anything. This includes sending the document to the external app.
This bug didn't appear on the iPhone, but on the iPad it gives an error because the popover architecture works a bit differently and it ends up trying to draw it when it's deallocated. That's what alerted me to the bug.
This bug also appears on iPhone/iPod. Just set:
#property (nonatomic, retain) UIDocumentInteractionController *docController;
and it will be retain and the document passed to the new application.
it's enough to add the following code:
[interactionController retain];

Resources