UIDocumentPickerViewController not calling didPickDocumentAtURL on Mac Catalyst - ios

I have this code in a UIViewController that confirms to UIDocumentPickerDelegate:
- (void)openTextFilePicker {
NSArray *UTIs = [NSArray arrayWithObjects:#"public.text", nil];
[self openFilePicker:UTIs];
}
- (void)openFilePicker:(NSArray *)UTIs {
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:UTIs inMode:UIDocumentPickerModeImport];
documentPicker.delegate = self;
documentPicker.popoverPresentationController.barButtonItem = self.importButton;
[self presentViewController:documentPicker animated:TRUE completion:nil];
}
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURLs:(NSArray<NSURL *> *)urls {
[self documentPicker:controller didPickDocumentAtURL:[urls firstObject]];
}
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url {
NSLog(#"picked document %#", url);
}
- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller {
NSLog(#"cancelled");
}
This works fine in iOS. In Mac Catalyst, the file picker opens, I can navigate and select a file, but when I click the Open button in the picker, neither didPickDocumentAtURLs nor didPickDocumentAtURL are called. However, if I click the Cancel button in the picker, documentPickerWasCancelled is called.
When I click Open, this error appears in the console:
Failed to associate thumbnails for picked URL file:///**** with the
Inbox copy file:///****: Error Domain=QLThumbnailErrorDomain Code=102
"(null)" UserInfo={NSUnderlyingError=0x600000da9a10 {Error
Domain=GSLibraryErrorDomain Code=7 "no storage for file:///****"
UserInfo={NSDescription=no storage for file:///****}}}
I thought that might mean I had a problem with my sandbox security settings, but when I change the picker mode to UIDocumentPickerModeOpen, that error no longer occurs but didPickDocumentAtURL still isn't called. Anyway, here are my sandbox settings:
I've seen posts about the document picker opening blank, but that's not the problem here. I've only seen one post that seems to confirm it does work, but that was using Swift ... could it be working in Swift but broken in Objective C? Is there something else I'm missing to make this work?
UPDATE
Here's a new Xcode project with the minimum code to demonstrate the problem. As with my full project, this works fine on iOS, but doesn't call the didPickDocument... delegate methods on Mac.

As far as I see you've just made typo in method signature, the correct is
- (void)documentPicker:(UIDocumentPickerViewController *)controller
didPickDocumentsAtURLs:(NSArray <NSURL *>*)urls {
NSLog(#"picked URLs %#", urls);
// selecting multiple documents is cool, but requires iOS 11
[self documentPicker:controller didPickDocumentAtURL:[urls firstObject]];
}
on iOS worked because deprecated legacy one still supported
- (void)documentPicker:(UIDocumentPickerViewController *)controller
didPickDocumentAtURL:(NSURL *)url;
but macOS/Catalyst does not, so your delegate just not called due to absent method.
Tested and works with Xcode 11.2

Swift version of new API that works on Catalyst is:
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
// handle urls
}

Related

Sinch App-to-Phone not working

I'm trying to implement app to phone calling from Sinch for IOS. I have successfully implemented app to app calling which means that the SDK is properly set up in my app. However the app to phone for some reason is not working:
In my MainViewController.m, I have the following:
- (id<SINClient>)client {
return [(JSQAppDelegate *)[[UIApplication sharedApplication] delegate] client];
}
Then, in an alertView:
if ([self.client isStarted]) {
id<SINCall> call = [self.client.callClient callPhoneNumber:#"+46000000000"]; //Testing the phone number as advised by Sinch!
[self showCallController:call appToAppCall:NO];
}
Which call the following method:
-(void)showCallController: (id<SINCall>)call appToAppCall: (BOOL)appToapp
{
MMLCallingViewController *callView = [self.storyboard instantiateViewControllerWithIdentifier:#"CallingView"];
callView.call = call;
callView.callReceiverName = _theRecipient;
callView.calleeID = _theRecipientId;
if (!appToapp) {
callView.typeOfCall = #"phone";
callView.callStateLbl.text = #"Phone";
}
else {
callView.typeOfCall = #"app";
}
[self presentViewController:callView animated:YES completion:nil];
}
Now each time, I tried to test the call - I have the following problem:
The call view show, then stop suddenly with the below message showing in the console:
[appDelegate client:logMessage:area:severity:timestamp:] [Line 590] virtual void rebrtc::SetSDPObserver::OnFailure(const std::string &)Failed to set remote answer sdp: Offer and answer descriptions m-lines are not matching. Rejecting answer.
[appDelegate client:logMessage:area:severity:timestamp:] [Line 590] Failed to set remote answer sdp: Offer and answer descriptions m-lines are not matching. Rejecting answer.
My Sinch SDK version is: 3.7.1-0313526 - with Xcode 6.3 - IOS SDK 8.3
My Parse SDK version is 1.7.4
I have tried to look everywhere and read all the tutorials on Sinch! website about calling, and cannot find any clue for help.
Any help will be greatly appreciate.
Thanks in advance.

Facebook iOS SDK 4.1.0 Share Callback

Using the FBSDK mentioned in the title of this question, I present a simple share dialog in a view controller:
// Setup the content for the share
FBSDKShareLinkContent *content = [[FBSDKShareLinkContent alloc] init];
content.contentURL = linkUrl;
content.contentDescription = description;
content.contentTitle = title;
content.imageURL = imageUrl;
// Show the share dialog
[FBSDKShareDialog showFromViewController:controller
withContent:content
delegate:someDelegate];
And implement the delegate method...
- (void)sharer:(id<FBSDKSharing>)sharer didCompleteWithResults:(NSDictionary *)results
{
NSLog(#"Sweet, they shared.");
}
So far so good, as long as the user has the Facebook application installed on their device. The issue arises when the user does not have Facebook installed. If this is the case, Safari opens up to a web version of Facebook's login flow (this is fine), but if you then switch back to the original application without logging into Facebook / performing any additional tasks, the completion delegate method shown above is called.
Does anyone have any experience with a workaround for this? It seems like there should be a reliable way for determining whether or not the post did indeed occur.
Note: The above code is pretty pseudo-ish. In the actual implementation I have indeed implemented all of the delegate call backs (didComplete, didCancel, and didFail).
Edit: It turns out, the results dictionary is empty when the completion method is called if the Facebook app is installed on the device. To overcome this, a check needs to be done to see if Facebook is installed first.
Of course after posting I stumbled upon the answer. The results dictionary returned in the didCompleteWithResults method contains a postId key if the share actually occurred. So the logic is as simple as:
- (void)sharer:(id<FBSDKSharing>)sharer didCompleteWithResults:(NSDictionary *)results
{
NSURL *fbURL = [NSURL URLWithString:#"fb://"];
if (![[UIApplication sharedApplication] canOpenURL:fbURL])
if (results[#"postId"]) {
NSLog(#"Sweet, they shared, and Facebook isn't installed.");
} else {
NSLog(#"The post didn't complete, they probably switched back to the app");
}
} else {
NSLog(#"Sweet, they shared, and Facebook is installed.");
}
}
Although this works, it doesn't seem to be a very safe way of going about things (what if Facebook changes the key from "postId" to something else in the future? Unlikely but you get my point).

UIImagePickerController occasionally freezing up

I use UIImagePickerController in an Unity app. It occasionally freezes when the user presses "done". It happens most often on 3GS — about every third time — but I also had an occasional freeze on iPhone 5. This bug appears on iOS from 4.3 to 7.0. I wasn't able to determine what factors correlate with the freeze. I don't get a memory warning when I get this freeze either.
There are no errors in the log, no crashlog whatsoever. The app continues to run behind UIImagePickerController as normal. There are a lot of messages in the console that seem related, like "deny file-write-data /private/var/mobile/Media/PhotoData", but all of them can occasionally appear both when freeze is present and when everything is working alright.
Here's how I show the picker:
- (void)showPicker:(UIImagePickerControllerSourceType)type
{
imgPicker = [[[CustomPhotoPicker alloc] init] autorelease];
imgPicker.delegate = self;
imgPicker.sourceType = type;
imgPicker.allowsEditing = _pickerAllowsEditing;
// wrap and show the modal
[self showViewControllerModallyInWrapper:imgPicker];
}
And here're the delegate methods:
- (void)imagePickerController:(UIImagePickerController*)imgPicker didFinishPickingMediaWithInfo:(NSDictionary*)info
{
NSLog( #"imagePickerController didFinishPickingMediaWithInfo");
// If the freeze is present, this method isn't called
}
- (void)imagePickerController:(UIImagePickerController *)imgPicker
didFinishPickingImage:(UIImage *)image
editingInfo:(NSDictionary *)editingInfo
{
NSLog( #"imagePickerController didFinishPickingImage");
// Tried to use deprecated callback. If the freeze is present, this method isn't called either.
}
I would decide that it's a bug inside the UIImagePickerController, but none of iOS developers that don't use Unity ever encountered this problem, and I would suppose that such a bug would already be fixed if it was present in 4.3.
Thre're are a workaround: u can mute CFRunLoopRunInMode in UnityAppController.mm, like this:
- (void)repaintDisplayLink
{
[_displayLink setPaused: YES];
{
static const CFStringRef kTrackingRunLoopMode = CFStringRef(UITrackingRunLoopMode);
if (![EtceteraManager picking])
{
while (CFRunLoopRunInMode(kTrackingRunLoopMode, kInputProcessingTime, TRUE) == kCFRunLoopRunHandledSource)
;
}
}
}

iOS webViewDidFinishLoading not being called

I have a UIWebView and want to display an activity indicator while it is loading. And then hide it when the webViewDidFinishLoading. The only problem is that I am getting this NSURLErrorDomain error -999 thing going on. After searching around I found this fix which works to not display any error message but my webViewDidFinishLoading doesn't ever get called to get rid of my activity indicator and other stuff that I have going on. I guess I could just make a call to the didFinishLoading method in my webViewDidFailWithError method if it fails with -999 but that seems super hacky and wrong. Any ideas on how to fix this?
edit*
I have figured out where the webview was being asked to load twice so I was able to get rid of the error -999. However, it seems neither of the delegate methods are being called unless I try to load the webview twice (in which case the webViewDidFinishLoading method is only called once).
- (void)viewDidLoad
{
self.webView.delegate = self;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(refresh)
name:#"DidBecomeActive"
object:nil];
[super viewDidLoad];
}
-(void)refresh{
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://myapp.com/app/"]]];
self.webView.scrollView.bounces = NO;
}
- (void)webViewDidFinishLoading:(UIWebView *)wv
{
NSLog(#"finished loading");
[self.activityInd stopAnimating];
[self.view bringSubviewToFront:wv];
}
- (void)webView:(UIWebView *)wv didFailLoadWithError:(NSError *)error
{
NSLog(#"Failed: %#", error);
if([error code] == NSURLErrorCancelled){
return;
}
[self.activityInd stopAnimating];
[[[UIAlertView alloc] initWithTitle:#"Can't find server" message:#"Check your internet connection and try again." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil]show];
}
Did u assigned the UIWebView delegates to its object like the following
webViewObject.delegate = self
Copy/Paste error.
- (void)webViewDidFinishLoading:(UIWebView *)wv
Should be changed to:
- (void)webViewDidFinishLoad:(UIWebView *)wv
implemente the protocol "UIWebViewDelegate" in .h file
In case you ended up here because you're wondering why your delegate methods aren't being called when the bug wasn't due to an incorrectly written delegate method:
Say your webview is normally instantiated via Interface Builder, but you forget to hook it up correctly (meaning it isn't instantiated). You can still set its delegate (e.g., self.webview.delegate = self;) without crashing or exceptions (provided self conforms to the UIWebViewDelegate protocol).
Similarly, you can load HTML into it (e.g., [self.webview loadHTMLString:someHTMLString baseURL:nil];) and the app will continue along happily without complaints. This would take you to an awkward situation where you've set the delegate, written the delegate methods correctly, loaded something into the webview, but your delegate methods will never fire.
So the advice for that situation: make sure you double check that your webview is connected properly (to the correct instance property/variable) in Interface Builder.

blank QLPreviewController in iOS application

I am trying to display a file using QLPreviewController. The QL view displays correctly (is pushed on top of my Navigation Controller) but the content is blank. However, no errors are displayed and application doesn't crash.
Checks on existence of file return true. (A proof is that if I use [self.docInteractionController presentPreviewAnimated:YES]; where docInteractionController is a UIDocumentInteractionController the file is correctly shown).
The code is taken directly from Apple sample code DocInteraction.
previewController.dataSource = self;
previewController.delegate = self;
// start previewing the document at the current section index
previewController.currentPreviewItemIndex = 0; //I want the first (and only) document
[[self navigationController] pushViewController:previewController animated:YES];
[previewController release];
The current view is a QLPreviewControllerDataSource, QLPreviewControllerDelegate,, and the delegate methods are as follow:
- (NSInteger) numberOfPreviewItemsInPreviewController: (QLPreviewController *) controller
{
return self.documentURLs.count;
}
- (id)previewController:(QLPreviewController *)previewController previewItemAtIndex: (NSInteger)index
{
return [self.documentURLs objectAtIndex:index];
}
documentURLs is a NSArray that contains the fileURLs of the documents. The same fileURL passed to the UIDocumentInteractionController displays correctly. I don't necessarily have to use QuickLook, I may just rely on UIDocumentInteractionController, however the fact that it's not working is really annoying.
Thank you in advance
Giovanni
Make a sample that demoes the issue. If you find that it still occurs on iOS 7, pls file a bug report.
I reported a bug on this class (pass nil URL to get loading indicator) and it got fixed within 2 weeks.

Resources