I'm working on an old iOS app that started with objective-C + UIKit and has being migrated to Swift + SwiftUI. Currently its code is mostly Swift + SwiftUI but it has still some objective-C and some UIKit ViewControllers.
One of the SwiftUI views uses fileImporter to open Files App and select a file from the device. This has been working well until iOS 18 is launched. With iOS 18 the file picker is not launching correctly and is frozen in every simulator (the unique real device I've could test with iOS 18 seemed to work correctly).
I managed to clone my project and leave it with the minimal amount of files to reproduce this error. This is the code:
AppDelegate.h
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate> {}
@property (strong, nonatomic) UIWindow *window;
@end
AppDelegate.m
#import "AppDelegate.h"
#import "MyApp-Swift.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application 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;
}
@end
FirstViewBuilder.swift
import SwiftUI
@objc class FirstViewBuilder: NSObject {
private var view: UIHostingController<FirstView>
@objc override init() {
self.view = MyHostingController(rootView: FirstView())
}
@objc func show() {
let app = UIApplication.shared.delegate as? AppDelegate
let window = app?.window
window?.backgroundColor = .white
// Use navigationController or view directly depending on use
window?.rootViewController = view
}
}
FirstView.swift
import SwiftUI
struct FirstView: View {
@State var hasToOpenFilesApp = false
var body: some View {
VStack(alignment: .leading, spacing: 0) {
Button("Open Files app") {
hasToOpenFilesApp = true
}.fileImporter(isPresented: $hasToOpenFilesApp, allowedContentTypes: [.text]) { result in
switch result {
case .success(let url):
print(url.debugDescription)
case .failure(let error):
print(error.localizedDescription)
}
}
}
}
}
And finally, MyHostingController
import SwiftUI
class MyHostingController<Content>: UIHostingController<Content> where Content: View {
override init(rootView: Content) {
super.init(rootView: rootView)
}
@objc required dynamic init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.hidesBackButton = true
}
}
Launching this in an iPhone 13 Pro (18.2) simulator I click on Open Files App, it takes 2 seconds to open it, and it opens full screen (not like a modal). Buttons on the top are behind the status bar and buttons at the bottom are behind the Home indicator. But it's worse because the user can't interact with this view, it's frozen.
I created a fresh SwiftUI project just with this unique view and the fileimport worked as expected so I thought the problem was due to embed the SwiftUI view inside the UIHostingController. So I made these modifications to the minimal project:
Remove the files AppDelegate, FirstViewBuilder and MyHostingController.
Create this SwiftUI App file
import SwiftUI
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
FirstView()
}
}
}
And again the same problem with iOS 18.
But if I launch this exact project in an iPhone 13 Pro (17.4) simulator and open the files apps (now it opens almost instantly) it works OK and shows the file picker as a modal, as expected, and I can interact with it and select files.
Last thing I've tried is removing LaunchScreen.xib from my project and Launch screen interface file base name key from my info.plist but the problem keeps happening.
I guess it must be due to my project configuration (too old) but I have no more ideas of where to look at.
The possibility of having a fresh SwiftUI project and "move" the old project to the new one could take me several weeks and I discard it by the moment.
Could I use another method to select files from SwiftUI views with iOS 18?
Explore the various UI frameworks available for building app interfaces. Discuss the use cases for different frameworks, share best practices, and get help with specific framework-related questions.
Post
Replies
Boosts
Views
Activity
The pitch slider is not supported on tvOS yet it displays when using the Map() view. Does anyone know how to hide it? It's really getting in the way of my UI.
Starting from Sequoia release 15.2 apps crash with following call stack, when adding static text controls. First call to [NSTextField setStringValue] causes following crash
0 libobjc.A.dylib 0x19f2f5820 objc_msgSend + 32
1 AppKit 0x1a3355460 -[NSCell _objectValue:forString:errorDescription:] + 144
2 AppKit 0x1a3355348 -[NSCell setStringValue:] + 48
3 AppKit 0x1a33af9fc -[NSControl setStringValue:] + 104
4 AppKit 0x1a3d1f190 -[NSTextField setStringValue:] + 52
It happens on specific MacBook Pro models(16 in MacBook Pro).
Crash analysis found that isa pointer of the object was corrupted for the object NSCell. Enabled Zombies in debugging, not found any issue. Also tried address sanitizer. Since the issue started with a recent release of macOS, any changes in the Appkit in the recent releases trigger the crash? Any help/suggestions would be appreciated.
Below is my sample code. On the Home page, when I click "show sheet," the sheet page expands, and the StateObject inside the sheet is initialized once. However, when I click "show Fullscreen" and then click "show sheet" inside the fullscreen page, the sheet gets initialized twice.
However, if I remove navigationDestination, this issue does not occur.
This problem causes the network request in the sheet page to be triggered multiple times.
Can someone tell me the reason?
enum TestRouter: String, Hashable {
case test
var targetView: some View {
Text("test")
}
var title: String {
return "test title"
}
}
@MainActor
struct NavigationInnerView<Content>: View where Content: View {
var contentView: () -> Content
@MainActor public init(@ViewBuilder contentView: @escaping () -> Content) {
self.contentView = contentView
}
var body: some View {
NavigationStack() {
contentView()
.navigationDestination(for: TestRouter.self) { route in
route.targetView
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
struct ContentView: View {
@State var showFullScreen: Bool = false
@State var showSheet: Bool = false
var contentView: some View {
VStack {
VStack {
Text("Home")
Button {
showFullScreen = true
} label: {
Text("show fullscreen")
}
Button {
showSheet = true
} label: {
Text("show sheet ")
}
}
}
}
var body: some View {
NavigationInnerView {
contentView
.fullScreenCover(isPresented: $showFullScreen) {
NavigationInnerView {
FullScreenContentView()
}
}
.sheet(isPresented: $showSheet) {
NavigationInnerView {
SheetContentView()
}
}
}
}
}
class FullScreenViewModel: ObservableObject {
@Published var content: Bool = false
init() {
print("Full Screen ViewModel init")
}
}
struct FullScreenContentView: View {
@Environment(\.dismiss) var dismiss
@State var showSheet: Bool = false
@StateObject var viewModel: FullScreenViewModel = .init()
init() {
print("Full screen view init")
}
var body: some View {
VStack {
Text("FullScreen")
Button {
dismiss()
}label: {
Text("dismiss")
}
Button {
showSheet = true
} label: {
Text("show sheet")
}
}
.sheet(isPresented: $showSheet) {
NavigationInnerView {
SheetContentView()
}
}
}
}
class SheetViewModel: ObservableObject {
@Published var content: Bool = false
init() {
print("SheetViewModel init")
}
}
struct SheetContentView: View {
@Environment(\.dismiss) var dismiss
@StateObject var viewModel = SheetViewModel()
init() {
print("sheet view init")
}
var body: some View {
Text("Sheet")
Button {
dismiss()
} label: {
Text("dismiss")
}
}
}
#Preview {
ContentView()
}
I am trying to support dragging out a 'file' object from my app into Finder, on macOS. I have my object conform to Transferable and the files are saved on disk locally, so I just want to pass it the URL. This works fine when dragging out to other apps, like Notes or Mail, but not in Finder. I setup a ProxyRepresentation as well, as suggested by another thread, but it doesn't seem to help. Is there any other setup I need to do in the Xcode project file for it to work, or is there something else that I'm missing?
@available(iOSApplicationExtension 17.0, macOSApplicationExtension 14.0, *)
extension FileAttachments: Transferable {
public static var transferRepresentation: some TransferRepresentation {
FileRepresentation(exportedContentType: UTType.content) { content in
SentTransferredFile(content.fullFileURL(), allowAccessingOriginalFile: false)
}
.exportingCondition { file in
if let fileUTI = UTType(filenameExtension: file.fullFileURL().pathExtension), let fileURL = file.fullFileURL() {
print("FileAttachments: FileRepresentation exportingCondition fileUTI: \(fileUTI) for file: \(fileURL)")
return fileUTI.conforms(to: UTType.content)
}
return false
}
.suggestedFileName{$0.fileRenamedName}
ProxyRepresentation { file in
if let fileURL = file.fullFileURL() {
print("FileAttachments: ProxyRepresentation returning file")
return fileURL
}
return file.fullFileURL()!
}
}
}
Hello.
I have a scenario where a hover effect is being shown for a button that is disabled. Usually this doesn't happen but when you wrap the button in a Menu it doesn't work properly.
Here is some example code:
struct ContentView: View {
var body: some View {
NavigationStack {
Color.green
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Menu("Menu") {
Button("Disabled Button") {}
.disabled(true)
.hoverEffectDisabled() // This doesn't work.
Button("Enabled Button") {}
}
}
}
}
}
}
And here is what it looks like:
This looks like a SwiftUI bug. Any help is appreciated, thank you!
I'm creating an app which gamifies Screen Time reduction. I'm running into an issue with apples Screen Time setting where the user can disable my apps "Screen Time access" and get around losing the game.
Is there a way to detect when this setting is disabled for my app? I've tried using AuthorizationCenter.shared.authorizationStatus but this didn't do the trick. Does anyone have an ideas?
I would like to get user's heart rate zones values in my watchOS app, is there any way to get it from HealthKit?
Furthermore, is it possible to display the Apple heart rate zones widget in my watchOS app?
macOS: 15.0
macFUSE: 4.8.3
I am using rclone + macFUSE and mount my netdisk where it has created three subdirectories in its root directory: /user, /share, and /group.
When I save a file to /[root]/user using NSSavePanel and name it test.txt, I expect the file to be saved as:
/[root]/user/test.txt
However, occasionally, the delegate method:
- (BOOL)panel:(id)sender validateURL:(NSURL *)url error:(NSError **)outError {
}
returns an incorrect path:
/[root]/test.txt
This issue only occurs when selecting /user. The same operation works correctly for /share and /group.
Is there any logs I could provide to help solving this issue?
Many thanks!
Is there any way to change the height of the "day" cells in the UICalendarView? The view is very tall on the screen and I'd like to shorten it so I can put more content below it without using a scroll view.
I'm using SwiftUI with a UICalendarView with UIViewRepresentable. The calendar will have default decorations to indicate a date with events.
I'm getting the following error in my SwiftUI code:
"Main actor-isolated property 'avatarImage' can not be referenced from a Sendable closure"
I don't understand how to fix it.
This happens in the following code:
You can copy-paste this into an empty project and make sure to have Swift 6 enabled under the Build Settings > Swift Language Version
import PhotosUI
import SwiftUI
public struct ContentView: View {
@State private var avatarItem: PhotosPickerItem?
@State private var avatarImage: Image?
@State private var avatarData: Data?
public var body: some View {
VStack(spacing: 30) {
VStack(alignment: .center) {
PhotosPicker(selection: $avatarItem, matching: .images) {
if let avatarImage {
avatarImage
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 100, height: 100)
.foregroundColor(.gray)
.background(.white)
.clipShape(Circle())
.opacity(0.75)
.overlay {
Image(systemName: "pencil")
.font(.title)
.shadow(radius: 5)
}
} else {
Image(systemName: "person.circle.fill")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 100, height: 100)
.foregroundColor(.gray)
.background(.white)
.clipShape(Circle())
.opacity(0.75)
.overlay {
Image(systemName: "pencil")
.font(.title)
.shadow(radius: 5)
}
}
}
}
}
.onChange(of: avatarItem) {
Task {
if let data = try? await avatarItem?.loadTransferable(
type: Data.self
) {
if let processed = processImage(data: data) {
avatarImage = processed.image
avatarData = processed.data
} else {
}
}
}
}
}
private func processImage(data: Data) -> (image: Image?, data: Data?)? {
guard let uiImage = UIImage(data: data)?.preparingForDisplay() else {
return nil
}
// Check original size
let sizeInMB = Double(data.count) / (1024 * 1024)
// If image is larger than 1MB, compress it
if sizeInMB > 1.0 {
guard let compressedData = uiImage.compress() else { return nil }
return (Image(uiImage: uiImage), compressedData)
}
return (Image(uiImage: uiImage), data)
}
}
#Preview {
ContentView()
}
public extension UIImage {
func compress(to maxSizeInMB: Double = 1.0) -> Data? {
let maxSizeInBytes = Int(
maxSizeInMB * 1024 * 1024
) // Convert MB to bytes
var compression: CGFloat = 1.0
let step: CGFloat = 0.1
var imageData = jpegData(compressionQuality: compression)
while (imageData?.count ?? 0) > maxSizeInBytes, compression > 0 {
compression -= step
imageData = jpegData(compressionQuality: compression)
}
return imageData
}
}
The SwiftUI Playground code below demonstrates that a .jpeg image can be read and written to the iOS file system. While, a.png image can only be read; the writing request appears to be ignored. Can anyone please tell me how to code to save a .png image using SwiftUI to the iOS file system.
Code:
import SwiftUI
import UniformTypeIdentifiers
/*
(Copied from Playground 'Help' menu popup.)
UIImage Summary
An object that manages image data in your app.
You use image objects to represent image data of all kinds, and the UIImage class is capable of managing data for all image formats supported by the underlying platform. Image objects are immutable, so you always create them from existing image data, such as an image file on disk or programmatically created image data. An image object may contain a single image or a sequence of images for use in an animation.
You can use image objects in several different ways:
Assign an image to a UIImageView object to display the image in your interface.
Use an image to customize system controls such as buttons, sliders, and segmented controls.
Draw an image directly into a view or other graphics context.
Pass an image to other APIs that might require image data.
Although image objects support all platform-native image formats, it’s recommended that you use PNG or JPEG files for most images in your app. Image objects are optimized for reading and displaying both formats, and those formats offer better performance than most other image formats. Because the PNG format is lossless, it’s especially recommended for the images you use in your app’s interface.
Declaration
class UIImage : NSObject
UIImage Class Reference
*/
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ImageFileDoc: FileDocument {
static var readableContentTypes = [UTType.jpeg, UTType.png]
static var writableContentTypes = [UTType.jpeg, UTType.png]
var someUIImage: UIImage = UIImage()
init(initialImage: UIImage = UIImage()) {
self.someUIImage = initialImage
}
init(configuration: ReadConfiguration) throws {
guard let data = configuration.file.regularFileContents,
let some = UIImage(data: data)
else {
throw CocoaError(.fileReadCorruptFile)
}
self.someUIImage = some
}
func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
switch configuration.contentType {
case UTType.png:
if let data = self.someUIImage.pngData() {
return .init(regularFileWithContents: data)
}
case UTType.jpeg:
if let data = self.someUIImage.jpegData(compressionQuality: 1.0) {
return .init(regularFileWithContents: data)
}
default:
break
}
throw CocoaError(.fileWriteUnknown)
}
}
struct ContentView: View {
@State private var showingExporterPNG = false
@State private var showingExporterJPG = false
@State private var showingImporter = false
@State var message = "Hello, World!"
@State var document: ImageFileDoc = ImageFileDoc()
@State var documentExtension = ""
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text(message)
Button("export") {
if documentExtension == "png" {
message += ", showingExporterPNG is true."
showingExporterPNG = true
}
if documentExtension == "jpeg" {
message += ", showingExporterJPG is true."
showingExporterJPG = true
}
}
.padding(20)
.border(.white, width: 2.0)
.disabled(documentExtension == "")
Button("import") {
showingImporter = true
}
.padding(20)
.border(.white, width: 2.0)
Image(uiImage: document.someUIImage)
.resizable()
.padding()
.frame(width: 300, height: 300)
}
// exporter .png
.fileExporter(isPresented: $showingExporterPNG, document: document, contentType: UTType.png) { result in
switch result {
case .success(let url):
message += ", .\(documentExtension) Saved to \(url.lastPathComponent)"
case .failure(let error):
message += ", Some error saving file: " + error.localizedDescription
}
}
// exporter .jpeg
.fileExporter(isPresented: $showingExporterJPG, document: document, contentType: UTType.jpeg) { result in
switch result {
case .success(let url):
message += ", .\(documentExtension) Saved to \(url.lastPathComponent)"
case .failure(let error):
message += ", Some error saving file: " + error.localizedDescription
}
}
// importer
.fileImporter(isPresented: $showingImporter, allowedContentTypes: [.png, .jpeg]) { result in
switch result {
case .failure(let error):
message += ", Some error reading file: " + error.localizedDescription
case .success(let url):
let gotAccess = url.startAccessingSecurityScopedResource()
if !gotAccess {
message += ", Unable to Access \(url.lastPathComponent)"
return
}
documentExtension = url.pathExtension
guard let fileContents = try? Data(contentsOf: url)
else {
message += ",\n\nUnable to read file: \(url.lastPathComponent)\n\n"
url.stopAccessingSecurityScopedResource()
return
}
url.stopAccessingSecurityScopedResource()
message += ", Read file: \(url.lastPathComponent)"
message += ", path extension is '\(documentExtension)'."
if let uiImage = UIImage(data: fileContents) {
self.document.someUIImage = uiImage
}else{
message += ", File Content is not an Image."
}
}
}
}
}
As you can see in the screenshot, the verification popups that appear when making a StoreKit purchase cut off the buttons. When typing the code into the input field, the window will also flicker and stutter with random view refreshes. Is this something I can configure/change? It's not a very pleasant experience for making an in app purchase.
When picking a photo in the gallery, whatever the orientation of the original image, size is always as landscape
if let image = info[convertFromUIImagePickerControllerInfoKey(UIImagePickerController.InfoKey.editedImage)] as? UIImage {
print("picked original", image.size)
For a portrait photo:
picked original (1122.0, 932.0)
For a landscape:
picked original (1124.0, 844.0)
What am I missing ?
I have a setup:
Collection view with compositional layout
a self sizing cell inside
a subview inside the cell
and unrelated view outside the collection view
I would like to:
modify the layout (constraints) of the cell inside the collection view with UIView.animate
trigger an animated layout update of collection view
synchronize the position of an unrelated view to the position of one of the subviews of a collection view cell
What I tried:
UIView.animate(withDuration: 0.25) {
cellViewReference.updateState(state: state, animated: false)
collectionView.collectionViewLayout.invalidateLayout()
collectionView.layoutIfNeeded()
someOtherViewOutsideCollectionView.center = cellViewReference.getPositionOfThatOneViewInWindowCoordinateSystem()
}
What I'm expecting:
after invalidateLayout, the layout update of the collection view is merely scheduled, but not yet performed
layoutIfNeeded forces an update on the collectionViewLayout + update on the frames of the views inside the UICollectionViewCells
all the frames become correct to what they will look like after the animation is performed
I call getPositionOfThatOneViewInWindowCoordinateSystem and it gives me the position of the view after the uicollectionview AND the cell's layout has updated
What happens instead:
getPositionOfThatOneViewInWindowCoordinateSystem returns me an old value
I am observing that the bounds of the cell didn't actually change during layoutIfNeeded
And moreover, the bounds change without animation, instantly
Question:
how to animate self sizing cell size change due relayout
how to synchronize outside views with collection views
When pushing a page in the navigation, changing the state of interactivePopGestureRecognizer causes the page to freeze.
Just like this:
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
CGFloat red = (arc4random_uniform(256) / 255.0);
CGFloat green = (arc4random_uniform(256) / 255.0);
CGFloat blue = (arc4random_uniform(256) / 255.0);
CGFloat alpha = 1.0; //
self.view.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(0, 0, 100, 44);
btn.backgroundColor = [UIColor redColor];
btn.center = self.view.center;
[btn setTitle:@"push click" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)click:(id)sender {
[self.navigationController pushViewController:[ViewController new] animated:YES];
}
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
self.navigationController.interactivePopGestureRecognizer.enabled = YES;
}
@end
Modern collection views use UICollectionViewDiffableDataSource with UICollectionView.CellRegistration and UICollectionView.dequeueConfiguredReusableCell(registration:indexPath:item).
There are runtime crashes when passing nil as argument for the item parameter. There's no clear documentation on whether optional items are allowed or not.
The function signature in Swift is:
@MainActor @preconcurrency func dequeueConfiguredReusableCell<Cell, Item>(using registration: UICollectionView.CellRegistration<Cell, Item>, for indexPath: IndexPath, item: Item?) -> Cell where Cell : UICollectionViewCell
Given the Item? type one would assume Optionals are allowed.
In Objective-C the signature is:
- (__kindof UICollectionViewCell *)dequeueConfiguredReusableCellWithRegistration:(UICollectionViewCellRegistration *)registration forIndexPath:(NSIndexPath *)indexPath item:(id)item;
I'm not sure, if there's implicit nullability bridging to the Swift API or if the Objective-C files has some explicit nullability annotation.
The crash is due to a swift_dynamicCast failing with:
Could not cast value of type '__SwiftNull' (0x10b1c4dd0) to 'Item' (0x10d6086e0).
It's possible to workaround this by making a custom Optional type like
enum MyOptional<T> {
case nothing
case something(T)
}
and then wrapping and unwrapping Item? to MyOptional<Item>. But this feels like unnecessary boilerplate.
With the current situation it's easy to ship an app where everything seems to work, but in production only certain edge cases cause nil values being used and then crashing the app.
Please clarify the allowed arguments / types for the dequeueConfiguredReusableCell function.
Either Optionals should be supported and not crash at runtime or the signatures should be changed so there's a compile time error, when trying to use an Item?.
Feedback: FB16494078
I'm trying to create a Notes-like experience in my SwiftUI app where users can:
Add photos as inline attachments within a TextEditor
Move these attachments around within the text (like they were text characters)
Delete attachments
Preview attachments in full screen
Have the attachments persist with the text content
Similar to how Apple Notes handles attachments, where images become part of the text flow and can be manipulated like text characters.
Current approach:
I've tried using a custom TextEditor with a separate array of attachments, but I'm struggling to make the attachments behave as inline elements that can be moved within the text.
RichTextEditor:
struct RichTextEditor: View {
@State var content: String = ""
@State private var isGalleryPresented = false
@State var pickedImage: PhotosPickerItem?
@State private var selectedImage: UIImage?
var body: some View {
TextEditor(text: $content)
.toolbar {
ToolbarItemGroup(placement: .keyboard) {
Button {
isGalleryPresented = true
} label: {
Label("Attached", systemImage: "paperclip")
}
}
}
.photosPicker(isPresented: $isGalleryPresented, selection: $pickedImage)
.onChange(of: pickedImage) { oldItem, newItem in
Task {
if let pickedImage = pickedImage,
let data = try? await pickedImage.loadTransferable(type: Data.self),
let loadedImage = UIImage(data: data) {
if let imageData = loadedImage.jpegData(compressionQuality: 0.7) {
Task {
await addPhoto(imageData)
}
}
}
}
}
}
private func addPhoto(_ imageData: Data) async {
await MainActor.run {
let photo = PhotoData(imageData: imageData)
content += "\n[image:\(photo.id)]"
}
}
}
My app is experiencing a recurring crash in the PRD environment, but it cannot be reproduced locally or in QA testing.
Below is the crash log—I’d appreciate any help or insights on how to diagnose and resolve this issue. Thank you!
0 libobjc.A.dylib 0x2354 objc_release_x0 + 16
1 libobjc.A.dylib 0x2354 objc_release + 16
2 libobjc.A.dylib 0x4e38 AutoreleasePoolPage::releaseUntil(objc_object**) + 204
3 libobjc.A.dylib 0x4b8c objc_autoreleasePoolPop + 260
4 FrontBoardServices 0x1f4d0 -[FBSWorkspace _calloutQueue_executeCalloutFromSource:withBlock:] + 176
5 FrontBoardServices 0x2eb90 -[FBSWorkspaceScenesClient _callOutQueue_sendDidCreateForScene:transitionContext:completion:] + 468
6 libdispatch.dylib 0x3fa8 _dispatch_client_callout + 20
7 libdispatch.dylib 0x79f0 _dispatch_block_invoke_direct + 284
8 FrontBoardServices 0x18378 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 52
9 FrontBoardServices 0x182f8 -[FBSMainRunLoopSerialQueue _targetQueue_performNextIfPossible] + 240
10 FrontBoardServices 0x181d0 -[FBSMainRunLoopSerialQueue _performNextFromRunLoopSource] + 28
11 CoreFoundation 0x73f3c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28
12 CoreFoundation 0x73ed0 __CFRunLoopDoSource0 + 176
13 CoreFoundation 0x76b94 __CFRunLoopDoSources0 + 344
14 CoreFoundation 0x75d2c __CFRunLoopRun + 840
15 CoreFoundation 0xc8274 CFRunLoopRunSpecific + 588
16 GraphicsServices 0x14c0 GSEventRunModal + 164
17 UIKitCore 0x3ee77c -[UIApplication _run] + 816
18 UIKitCore 0x14e64 UIApplicationMain + 340
I have the following code for generating a one page PDF:
@MainActor func render() -> URL {
let renderer = ImageRenderer(content: pdfView))
let url = URL.documentsDirectory.appending(path: "output.pdf")
renderer.render { size, context in
var document = CGRect(x: 0, y: 0, width: 2550, height: 3300)
guard let pdf = CGContext(url as CFURL, mediaBox: &document, nil) else {
return
}
pdf.beginPDFPage(nil)
context(pdf)
pdf.endPDFPage()
pdf.closePDF()
}
return url
}
I'm trying to write code to create a multi-page PDF if there is multiple ImageRenderers. I tried something shown below but I'm not sure how to properly implement.
@MainActor func render() -> URL {
let renderer = ImageRenderer(content: pdfView)
let url = URL.documentsDirectory.appending(path: "output.pdf")
for image in renderer {
image.render { size, context in
var page = generatePage(image: image)
}
}
return url
}
func generatePage(image: ImageRenderer<<#Content: View#>>) -> CGContext {
var view = CGRect(x: 0, y: 0, width: 2550, height: 3300)
guard let pdf = CGContext(url as CFURL, mediaBox: &view, nil) else {
return
}
pdf.beginPDFPage(nil)
context(pdf)
pdf.endPDFPage()
pdf.closePDF()
return pdf
}
Any guidance would be greatly appreciated. Thank you.