Whenever I try show the UIDocumentInteractionController with the method presentOptionsMenuFromRect no file is attached in the opening app and I get this in the console:
Couldn't get file size for (null): (null)
But if I test with presentOpenInMenuFromRect it works perfectly fine. I also use presentPreviewAnimated with its delegates and this works too. Also tested successfully switching to an UIActivityViewController. The file I try to open is a PDF stored in the local documents directory
let documentInteractionController = UIDocumentInteractionController.init(URL: url)
documentInteractionController.presentOptionsMenuFromRect(self.view.bounds, inView: self.view, animated: true)
Xcode: 7.3.1 (Swift)
iOS: 9.3 tested with simulator and device, deployment target is 8.0
Thanks
This happens because in your code, the UIDocumentInteractionController instance might be being released by reaching the end of a function, while it's needed to let the other app handle the file properly after selecting an option from the menu.
To avoid this problem, we need to store a strong reference to our document interaction controller in a place that will exist for the lifetime of the object's owner (i.e. a global variable) in order to keep it alive.
Note: Apparently, this behavior does not occur with some of the options from the Open In menu nor by sharing with AirDrop.
Related
I am using Xcode 14.2 on macOS Ventura 13.2, working on an iOS app initially created from Xcode's template via New Project > iOS > Document App. I am using Objective-C, not Swift. I am testing in the simulator's "iPad Pro (12.9 in) 6th Generation - iOS 16.2" module.
The template created a UIDocumentBrowserViewController subclass and a UIDocument subclass, which I've been filling in.
I have two problems.
First, the document browser is ignoring its own shouldShowFileExtensions property. I have it set to NO, and I have checked that it is still NO later during runtime; but the browser view still displays filename extensions.
Second, I'd really rather the browser displays the UIDocument.localizedName string instead of the filename. This is a read-only property of UIDocument which is supposedly overridable by the subclass to return whatever string you'd like. My UIDocument subclass's override is never being called.
The override looks like this:
- (NSString*)localizedName
{
return [self projectName];
}
I am not doing anything weird with my subclasses; I've done my best to follow Apple's guidelines and documentation meticulously. My app will create documents that later appear in the browser, and which can be opened again and displayed, so the basics are working; but I have no control over the display name of the documents in the browser.
What am I doing wrong? Thanks in advance for any help.
localizedName is not used by the document browser, or it would have to create a UIDocument for every file in the directories the user visits! This would have a huge performance impact. LocalizedName is only used, as explained in the documentation, to display the document’s name after it is open in error messages and the like.
There's a similar question that works on Objective-C, but I tried the same code in Swift and it never executes, neither in the main app, nor in the action extension.
My situation is similar to the one in the question above, that is, when running from the main app I want to use UIApplication.shared.open to open a link in Safari, but I want to ignore this part of the code on the App Extension.
The problem isn't finding out whether the app is running from an App Extension or not, but ignoring the code when building for the App Extension, so that the compiler does not give me the following error on build:
You could introduce a new Custom Flag (similar to the DEBUG flag) for the extension target. In your Build Settings look for the Custom Flags and add a new one (e.g. "EXTENSION"). Like here in the screenshot, but also do it for release.
In your Code you could then do something like
#if EXTENSION
// here goes code that is only compiled in the extension
#else
// here goes code that is only compiled outside the extension
#endif
Update: Please read the Apple provided documentation on App Extensions:
Some APIs Are Unavailable to App Extensions
Because of its focused role in the system, an app extension is ineligible to participate in certain activities. An app extension cannot:
Access a Application.shared object, and so cannot use any of the methods on that object
- Apple, App Extension Programming Guide
To programmatically find if the it the running extension via code it's really simple, just do this:
let bundleUrl: URL = Bundle.main.bundleURL
let bundlePathExtension: String = bundleUrl.pathExtension
let isAppex: Bool = bundlePathExtension == "appex"
// `true` when invoked inside the `Extension process`
// `false` when invoked inside the `Main process`
I am using RPSystemBroadcastPickerView to show a picker view, from which a user can select a broadcast service to record the screen. Based on documentation, preferredExtension should allow me to set which broadcast extension should the picker show.
The code is super simple:
let broadcastPickerView = RPSystemBroadcastPickerView(frame: CGRect(x: 0, y: 0, width: 51, height: 51))
view.addSubview(broadcastPickerView)
broadcastPickerView.preferredExtension = "com.milan.nosal.broadcast-extension"
broadcastPickerView.backgroundColor = .clear
broadcastPickerView.showsMicrophoneButton = false
where "com.milan.nosal.broadcast-extension" is the bundle identifier of the extension I want the picker to offer (I checked its correctness multiple times).
However, when the control is tapped, at first the pop up shows empty selection:
After you close it, and tap the control again, it shows the correct extension. This only happens when the app is installed (or reinstalled), after it shows, then it shows always.
Is this the iOS 12 beta bug, or am I doing something incorrectly? Can I "preregister" the extension to work around this?
EDIT:
After publishing the app, we encountered the same problem with our users, but this time not even tapping the control multiple times helps - the picker is always empty! It seems that the extension is installed correctly, because it can be launched from control center.
Running on official release now.
Note that this is for ANY iOS Version:
I just burned a full day on this. When you add the BroadCast extension, Apple will automatically add the highest possible iOS Version for the deployment target. You need to make sure this isn't higher than your physical device's iOS Version. You won't get any build errors, they just won't show your app in the broadcast extension list.
I think it is the apple's bug, but it was fixed in iOS 12.2 after I tested it.
I have the same issue, looks like Xcode has some issues how to install broadcastExtension with you app. For me, It is related only for Debug mode. To see correct UI, try to enable broadcasting once in old way (control center -> deep touch -> start broadcast), after that in your BroadcastPickerView you will see correct UI (you are pushing iOS to update information about the extension). Cannot reproduce in release mode.
You can find your exactly preferedExtension here:
When you add pickerView.preferredExtension exactly the Bundle Identifier, your app will be showed on the Recording App List. Hope this helps!
If I do not set ".preferredExtension", I see all extensions on the list.
I tested on iOS12 GM.
You add Broadcast Upload Extension into your project and get that Extension Bundle Identifier.
How to create Broadcast Upload Extension into your app?
Go to xcode - File - New - Target - Broadcast Upload Extension
Then Add this line into your app. when you created RPSystemBroadcastPickerView object.
broadCastPicker?.preferredExtension = "com.vikrant.YourApp.Extension"
For some reason when I call let realm = Realm() it stops processing (doesn't crash) my code. My app is still running, but the screen keep frozen.
When I try to open default.realm using realm browser app, it shows me:
Again, it doesn't crash my app. It is a kind of pause.
No braekepoints
I've already tried: cocoapods and xcode install
I've already tried run on simulator and device (iPad)
App already deleted
Project cleaned up
Derived data cleaned up
I can't record audio using the SpeakHere example app from apple. When I run the app in Simulator from within Xcode, it starts up normally, but when I press the record button, the error "Thread 1: EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)" occurs:
The log message about the missing root view controller at app startup is already there BEFORE the above error occurs and it is probably not connected to my problem.
I have downloaded the SpeakHere example project from the linked website (see top of this question), opened the fresh download in Xcode and directly started the app. I did not modify any setting and not any line of code. I've also searched on google and stackoverflow for this problem and didn't find a solution, although this problem must be very general.
I use Xcode Version 4.5.2 (4G2008a) and a MacBook Pro from late 2009 with Mac OS X 10.8.
I've also had a friend try this on his computer and he has the very same problem. He has the same OS and his XCode version is also 4.5.2.
I would now try older Xcode versions, but right now I don't like to download a few gigabytes for a trial'n'error approach on my connection.
Any help appreciated, including reports like "works for me with Xcode version ...". Thanks!
The problem occurs because in the method AQRecorder::StartRecord(CFStringRef inRecordFile), the function CFURLCreateWithString() fails and returns a pointer to nil. This is not detected and later on the code calls CFRelease() on this nil pointer, which causes the EXC_BREAKPOINT.
The purpose of the method CFURLCreateWithString() basically is to take a url string as input and return a pointer to a CFURL object as output. The problem here is that the input is not a url string. Instead, it's simply a path on the local file system without file:/ or the like as prefix. For this reason, this method fails.
The solution is to remove the not-working call to the method CFURLCreateWithString() and instead call a related method, namely CFURLCreateWithFileSystemPath(), which is prepared to take a local file system path and convert it to a CFURL:
In the method AQRecorder::StartRecord(CFStringRef inRecordFile), replace or comment out the line
url = CFURLCreateWithString(kCFAllocatorDefault, (CFStringRef)recordFile, NULL);
and insert
url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)recordFile, kCFURLPOSIXPathStyle, false);
at its place.
url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)recordFile, kCFURLPOSIXPathStyle, false);
The code above made my xcoce 4.6 compile and run in simulator, but it doesnot record my voice from my usb microphone, I test my microphone in the garash band application and sucessfully record and play my voice, and the dbmeter does not move at all, any way when I port it to the real device it work, it just can't record and play voice in my simulator.