I am engaged on an outdated iOS app that began with objective-C + UIKit and has being migrated to Swift + SwiftUI. Presently its code is generally Swift + SwiftUI but it surely has nonetheless some objective-C and a few UIKit ViewControllers.
One of many SwiftUI views makes use of fileImporter to open Recordsdata App and choose a file from the machine. This has been working effectively till iOS 18 is launched. With iOS 18 the file picker shouldn’t be launching appropriately and is frozen in each simulator (the distinctive actual machine I’ve might check with iOS 18 appeared to work appropriately).
I managed to clone my venture and depart it with the minimal quantity of recordsdata to breed this error. That is the code:
AppDelegate.h
#import
@interface AppDelegate : UIResponder {}
@property (robust, nonatomic) UIWindow *window;
@finish
AppDelegate.m
#import "AppDelegate.h"
#import "MyApp-Swift.h"
@interface AppDelegate ()
@finish
@implementation AppDelegate
- (BOOL)utility:(UIApplication *)utility didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
FirstViewBuilder *viewBuilder = [[FirstViewBuilder alloc] init];
[viewBuilder show];
return YES;
}
@finish
FirstViewBuilder.swift
import SwiftUI
@objc class FirstViewBuilder: NSObject {
non-public var view: UIHostingController
@objc override init() {
self.view = MyHostingController(rootView: FirstView())
}
@objc func present() {
let app = UIApplication.shared.delegate as? AppDelegate
let window = app?.window
window?.backgroundColor = .white
// Use navigationController or view immediately relying on use
window?.rootViewController = view
}
}
FirstView.swift
import SwiftUI
struct FirstView: View {
@State var hasToOpenFilesApp = false
var physique: some View {
VStack(alignment: .main, spacing: 0) {
Button("Open Recordsdata app") {
hasToOpenFilesApp = true
}.fileImporter(isPresented: $hasToOpenFilesApp, allowedContentTypes: [.text]) { end in
swap end result {
case .success(let url):
print(url.debugDescription)
case .failure(let error):
print(error.localizedDescription)
}
}
}
}
}
And eventually, MyHostingController
import SwiftUI
class MyHostingController: UIHostingController the place Content material: View {
override init(rootView: Content material) {
tremendous.init(rootView: rootView)
}
@objc required dynamic init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been applied")
}
override func viewDidLoad() {
tremendous.viewDidLoad()
navigationItem.hidesBackButton = true
}
}
Launching this and opening the file picker (it takes a few seconds) in an iPhone 13 Professional (18.2) simulator offers this:
And it does not reply to any contact, the app is frozen and I’ve to kill it.
I created a recent SwiftUI venture simply with this distinctive view and the fileimport labored as anticipated so I assumed the issue was because of embed the SwiftUI view contained in the UIHostingController.
So I made these modifications to the minimal venture:
- Take away the recordsdata AppDelegate, FirstViewBuilder and MyHostingController.
- Create this SwiftUI App file
import SwiftUI
@major
struct MyApp: App {
var physique: some Scene {
WindowGroup {
FirstView()
}
}
}
And once more the identical drawback with iOS 18.
But when I launch this actual venture in an iPhone 13 Professional (17.4) simulator and open the recordsdata apps (now it opens nearly immediately) it really works OK and reveals this, as anticipated, and I can work together with it and choose recordsdata:
Last item I’ve tried is eradicating LaunchScreen.xib from my venture and Launch display screen interface file base identify key from my data.plist however the issue retains occurring.
I suppose it have to be because of my venture configuration (too outdated) however I’ve no extra concepts of the place to take a look at.
The potential for having a recent SwiftUI venture and “transfer” the outdated venture to the brand new one might take me a number of weeks and I discard it by the second.
Might I take advantage of one other methodology to pick out recordsdata from SwiftUI views with iOS 18?