UIDocumentInteractionController - MailCompose not dismissing in iOS8 - ios8

I have a very strange (& serious) problem.
My app uses a UIDocumentInteractionController to share a PDF document.
When the user selects the "Mail" option in the controller's pop-up the MailCompose window is opened.
But, neither the Send nor Cancel button in this window causes the MailCompose window to be dismissed, meaning the user gets stuck and has to kill the app. The mail does go out though.
Here's the catch:
This happens only in iOS8 (both versions released so far) and only on apps installed via the AppStore. That EXACT same version of the app, when running on my device via USB debugging works fine.
Here's some code:
-(void)sharePDF:(id)sender
{
#try
{
NSURL *fileURL = [NSURL fileURLWithPath:currentFileObject.LocalPath];
if(fileURL)
{
//UIDocumentInteractionController
NSString *newPath;
#try
{
//Create a copy of the file for sharing with a friendly name
if (currentFileObject.isSpecialReport)
{
newPath = [svc saveReport:[NSData dataWithContentsOfURL:fileURL] ToFile:[NSString stringWithFormat:#"%#.pdf", currentFileObject.ReportName]];
}
else
{
newPath = [svc saveReport:[NSData dataWithContentsOfURL:fileURL] ToFile:[NSString stringWithFormat:#"%#.pdf", currentFileObject.PatientFullName]];
}
}
#catch (NSException *exception) {
return;
}
NSURL *newURL = [NSURL fileURLWithPath:newPath];
self.docController = [UIDocumentInteractionController interactionControllerWithURL:newURL];
self.docController.delegate = self;
if (currentFileObject.isSpecialReport)
{
self.docController.name = [NSString stringWithFormat:#"Pathology - %#", currentFileObject.ReportName];
}
else
{
self.docController.name = [NSString stringWithFormat:#"Pathology - %#", currentFileObject.PatientFullName];
}
[self.docController presentOptionsMenuFromBarButtonItem:btnShare animated:YES];
}
}
#catch (NSException *exception) {
return;
}
}
I do not implement any of the delegate methods since non of them are required, I also do not make use of the preview functionality.
What's most puzzling to me is that the app from the AppStore behaves differently than my local one although the code is identical. My next step is to use the new beta developer tools (Test Flight) to re-publish the app, hoping that I can replicate the problem.
EDIT: I found a similar question on SO here: Cannot dismiss email sheet invoked from UIDocumentInteractionController in iOS 8
After reading that post I think it worth mentioning that I submitted the app to the AppStore via XCode 5 (the last version before XCode 6). Can that really be a factor here? Does Apple not use the same version on their side as the version in which the app was originally built?

I think this is a bug in iOS 8, and if it's still not working for you, I don't think Apple are likely to fix it. I'd upgrade to Xcode 6 and see if that fixes it for you. (It did for us, as you've discovered).

Related

How do I open the "Share Menu" preferences on OSX?

Much like Safari, trying to implement a button that when clicked opens System Preferences > Extensions > Share Menu pane.
I have tried:
NSURL *URL = [NSURL URLWithString:#"x-apple.systempreferences:com.apple.preferences.extensions?Share_Menu"];
[[NSWorkspace sharedWorkspace] openURL:URL];
However it seems like that is not working on newer versions, any ideas?
You can use Scripting Bridge to do something like this:
SBSystemPreferencesApplication *systemPrefs =
[SBApplication applicationWithBundleIdentifier:#"com.apple.systempreferences"];
[systemPrefs activate];
SBElementArray *panes = [systemPrefs panes];
SBSystemPreferencesPane *notificationsPane = nil;
for (SBSystemPreferencesPane *pane in panes) {
if ([[pane id] isEqualToString:#"com.apple.preferences.extensions"]) {
notificationsPane = pane;
break;
}
}
[systemPrefs setCurrentPane:notificationsPane];
SBElementArray *anchors = [notificationsPane anchors];
for (SBSystemPreferencesAnchor *anchor in anchors) {
if ([anchor.name isEqualToString:#"Extensions"]) {
[anchor reveal];
}
}
Of course you need to add the ScriptingBridge framework to your project and a Scripting Bridge header file for system preferences. More details on how to use Scripting Bridge you can find in the developer documentation from Apple.
Hope this helps
Since macOS Ventura (13.0) you can call the URL
x-apple.systempreferences:com.apple.preferences.extensions?Sharing

Square connect API - Navigate back to app

I am able to open Register app from my app on iPad by passing amount.
Now, when I cancel this by clicking on X at top left, Register app doesn not open back my app.
Versions :
iOS : 10.1.1
Register App : 4.54.1
Xcode : 8.2
Any suggestions ? What I am missing ?
Code :
if (totalAmount)
{
NSError *error = nil;
SCCMoney *amount = [SCCMoney moneyWithAmountCents:9000 currencyCode:#"USD" error:&error];
if (error)
return;
NSURL *const callbackURL = [NSURL URLWithString:#"myapp-callback://abc"];
SCCAPIRequest *request = [SCCAPIRequest requestWithCallbackURL:callbackURL
amount:amount
userInfoString:#"Info"
merchantID:nil
notes:#"Coffee"
customerID:nil
supportedTenderTypes:SCCAPIRequestTenderTypeAll
clearsDefaultFees:NO
returnAutomaticallyAfterPayment:YES
error:&error];
if (![SCCAPIConnection performRequest:request error:&error])
{
DLog(#"Error with Register Payment");
}
}
Callback URL setup :
Xcode
Square Developer portal
You probably haven't registered myapp-callback://abc for your application.
If you look at the first step on this page:
https://docs.connect.squareup.com/articles/register-api-ios/
You'll need to add a URL scheme for your app to your info.plist like the Hello Charge sample has below, I'm guessing you don't have myapp-callback://abc in there and Square Register is unable to switch back to your app.
OK I got the issue.
URL scheme should be same in info.plist and at developer portal.
In my case it was myapp-callback://abc in info.plist and myapp-callback at developer portal.

LaunchServices: invalidationHandler called - iOS 8 share sheet

Seeing this error message in the logs, though not consistently, around the time that I use SLComposeViewController to open a Twitter or Facebook share sheet. I am not using any new iOS 8 API, just testing existing code on iOS 8. I see others have had this problem and even seen crashes when using other modal view controllers from the Cocoa Touch SDK.
LaunchServices: invalidationHandler called
Are there new precautions to take with SLComposeViewController and UIActivityViewController in iOS 8? Something else to consider?
Add this code after you present your activity view controller:
if ([activityVC respondsToSelector:#selector(popoverPresentationController)])
{
// iOS 8+
UIPopoverPresentationController *presentationController = [activityVC popoverPresentationController];
presentationController.sourceView = sender; // if button or change to self.view.
}
Looking at the developer forums: "That log message does not indicate any error on your part."
I had a similar problem with a UIDocumentInteractionController, where when I tapped outside it to dismiss it, or selected another app to open the document in, it would crash with the "LaunchServices: invalideationHandler called" console message displayed twice (only using iOS 8).
A workaround is to add the call to presentOpenInMenuFromRect:inView:animated to the main queue, i.e.
dispatch_async(dispatch_get_main_queue(), ^() {
[self.documentInteraction presentOpenInMenuFromRect:theRect inView:self.view animated:YES];
});
You may also need to define the sourceRect. I used the following code to display a SLComposeViewController from a tableView.
if ([controller respondsToSelector:#selector(popoverPresentationController)]) {
//get rect for this row in table
CGRect frame = [self.tableView rectForRowAtIndexPath:indexPath];
//convert table row frame to view reference
CGRect frameInView = [self.tableView convertRect:frame toView:self.view];
[controller popoverPresentationController].sourceRect = frameInView;
[controller popoverPresentationController].sourceView = self.view;
}
Regarding the auto-closing (not the crash):
I think it's probably related to the link you are trying to share. I'm seeing the same thing when trying to post music links (Spotify, SoundCloud,...). The same tweet works if I replace the link by a link to some non-media-content. I'll file radar on this to see whether it's intentional...
This gets rid of the Error message for me and works as expected. You have to get rid of the if statement that calls "isAvailableForServiceType:"
It should look like this. Happy coding.
SLComposeViewController *tweetSheet = [SLComposeViewController
composeViewControllerForServiceType:SLServiceTypeTwitter];
[tweetSheet setInitialText:#"Great fun to learn iOS programming at appcoda.com!"];
[self presentViewController:tweetSheet animated:YES completion:nil];
if ([tweetSheet respondsToSelector:#selector(popoverPresentationController)])
{
// iOS 8+
UIPopoverPresentationController *presentationController = [tweetSheet popoverPresentationController];
presentationController.sourceView = sender; // if button or change to self.view.
}

libPd XCode Sound Issue

Hi everyone,
I've made a patch with pure data to load and play samples that will then be loaded into xcode with libpd. This all works fine but when I run the xcode project I only get sound from the right channel of my headphones.
I'll attach a picture to show my patch, and you can see that the dac has a cable on each inlet, which is why I don't understand how it isn't playing the sound in both channels.
Please note I've only attached it to the top left sample for testing purposes.
Thanks in advance!
http://i46.tinypic.com/3531gmb.png
#andyvn22: is this what you are after? Sorry I'm new to XCode so I'm not too sure!
-(void)viewDidLoad {
[super viewDidLoad];
dispatcher = [[PdDispatcher alloc] init];
[PdBase setDelegate:dispatcher];
patch = [PdBase openFile:#"Patch.pd"
path:[[NSBundle mainBundle] resourcePath]];
if (!patch) {
NSLog(#"Failed to open patch!");
}
}
-(void)viewDidUnload {
[super viewDidUnload];
[PdBase closeFile:patch];
[PdBase setDelegate:nil];
}
// Omitting the remaining view controller methods...
#pragma mark - button callbacks
-(IBAction)playc1:(id)sender {
[PdBase sendBangToReceiver: #"c1"];
Try using PdAudioController's -configurePlaybackWithSampleRate:numberChannels:inputEnabled: method to set the channels to 2.

NSSharingService on mountain lion without sharing window

On mountain lion, I try the new sharing possiblities with the NSSharingService class of AppKit.framework
Everything goes fine with this kind of code
NSArray* array = #[ #"myText", [NSImage imageNamed:#"myImageFile"] ];
NSSharingService* sharingServiceFB = [NSSharingService sharingServiceNamed:NSSharingServiceNamePostOnFacebook];
[sharingServiceFB performWithItems:array];
But I'd like to do the same without the sharing window generated by the performWithItems function.
As I'm considering that the user of my application don't want to confirm that he want to send the message as he already have choosen that.
I don't see any "direct posting" function in this class.
Does it need to be done an other way ?
There is no way to do this other than implementing Facebook's API yourself, but if you don't mind the window appearing for half a second:
- (void)whatever {
NSArray* array = #[ #"myText", [NSImage imageNamed:#"myImageFile"] ];
NSSharingService* sharingServiceFB = [NSSharingService sharingServiceNamed:NSSharingServiceNamePostOnFacebook];
[sharingServiceFB performWithItems:array];
[self performSelector:#selector(pressReturn) withObject:nil afterDelay:0.5];
}
- (void)pressReturn {
CGEventRef keypress = CGEventCreateKeyboardEvent(NULL, 36, TRUE);
CGEventPost(kCGHIDEventTap, keypress);
}
Your users might not like it though...

Resources