Starting iOS 16 seeing some crashes related to pdf printing in the crash reporter. It looks like the issue is not so frequent. Also, I'm unable to reproduce the crash. Looks like the app crashes when the print preview dialog is opening. According to crash reports, there are some crashes on different iOS 16 versions: 16.0.0, 16.0.2, and 16.0.3.
Printing code:
let printInfo = UIPrintInfo.printInfo()
printInfo.jobName = "Printing Job Name"
self.printViewController = UIPrintInteractionController.shared
self.printViewController?.printInfo = printInfo
self.printViewController?.printingItem = pdfURL
self.printViewController?.present(from: barButtonItem, animated: true) { (controller, completed, error) in
self.printViewController = nil
}
Stack trace:
compare_key + 4 (CGPDFObject.c:134)
bsearch + 68 (bsearch.c:70)
CGPDFDictionaryGetUnresolvedObject + 68 (CGPDFDictionary.c:153)
CGPDFDictionaryGetObject + 44 (CGPDFDictionary.c:172)
CGPDFDictionaryGetDictionary + 44 (CGPDFDictionary.c:284)
get_pages_dictionary + 68 (pdf-reader.c:410)
pdf_reader_get_number_of_pages + 76 (pdf-reader.c:557)
-[UIPrintPreviewPageFetcher fetchNumberOfItems] + 76 (UIPrintPreviewPageFetcher.m:115)
-[UIPrintPreviewViewController collectionView:numberOfItemsInSection:] + 32 (UIPrintPreviewViewController.m:482)
-[UICollectionViewData _updateItemCounts] + 220 (UICollectionViewData.mm:335)
-[UICollectionViewData isIndexPathValid:validateItemCounts:] + 52 (UICollectionViewData.mm:348)
-[UICollectionViewData validatedGlobalIndexForItemAtIndexPath:] + 36 (UICollectionViewData.mm:778)
-[UICollectionView _cellForItemAtIndexPath:] + 108 (UICollectionView.m:7112)
-[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:animator:collectionViewAnimator:] + 1384 (UICollectionView.m:9357)
-[UICollectionView _updateRowsAtIndexPaths:updateAction:updates:] + 396 (UICollectionView.m:9104)
-[UICollectionView reloadItemsAtIndexPaths:] + 52 (UICollectionView.m:9124)
-[UIPrintPreviewViewController reloadVisibleItems:] + 256 (UIPrintPreviewViewController.m:568)
__63-[UIPrintPreviewViewController updatePdfURL:options:completed:]_block_invoke_2 + 44 (UIPrintPreviewViewController.m:305)
__NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 24 (NSOperation.m:1545)
-[NSBlockOperation main] + 104 (NSOperation.m:1564)
__NSOPERATION_IS_INVOKING_MAIN__ + 16 (NSOperation.m:2189)
-[NSOperation start] + 708 (NSOperation.m:2206)
There is full stack trace I got from the Organizer
Thanks!
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
So I'm trying to use MapKit in a SwiftUI project targeting iOS/iPadOS. MapKit is obviously pretty limited in SwiftUI, but I've been getting warnings trying to set up basic annotations for the user to interact with.
When I use a basic MapMarker everything is fine (although it's hard to do anything with it), but whenever I do anything with MapAnnotation, I get this warning in Xcode (14.0.1) whenever I move the map around:
[SwiftUI] Publishing changes from within view updates is not allowed, this will cause undefined behavior.
I'm no SwiftUI expert, and I get how to fix this issue when binding in something like a sheet, but I don't see how what I'm doing with MapAnnotation should be causing this.
It looks like a bug to me, possibly complaining about the $region binding, but maybe I'm wrong? Am I doing something wrong or is this a bug?
Below is some sample code that reproduces this easily for me (just launch an app with the below code and then drag the map around to see the constant warnings in Xcode). It's mostly an example from here: https://www.hackingwithswift.com/books/ios-swiftui/integrating-mapkit-with-swiftui
import SwiftUI
import MapKit
struct Location: Identifiable {
let id = UUID()
let name: String
let coordinate: CLLocationCoordinate2D
}
struct ContentView: View {
@State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 51.5, longitude: -0.12), span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2))
let locations = [
Location(name: "Buckingham Palace", coordinate: CLLocationCoordinate2D(latitude: 51.501, longitude: -0.141)),
Location(name: "Tower of London", coordinate: CLLocationCoordinate2D(latitude: 51.508, longitude: -0.076))
]
var body: some View {
Map(coordinateRegion: $region, annotationItems: locations) { location in
MapAnnotation(coordinate: location.coordinate) {
Circle()
.stroke(.red, lineWidth: 3)
.frame(width: 44, height: 44)
}
}
.navigationTitle("Map")
.edgesIgnoringSafeArea(.all)
}
}
Code to reproduce:
struct CrashView: View {
var body: some View {
ScrollView {
LazyVStack {
ForEach(0...100, id: \.self) { i in
LazyVGrid(columns: Array(repeating: .init(.fixed(100)), count: 3), content: {
ForEach(0...20, id: \.self) { i in
Color.red.opacity(Double(i + 1) / 20).frame(height: 300)
}
})
}
}
}
}
}
Important: it crashes on iOS 16.1 !!!
We have 21 grid item (3 item and 7 full lines) for every LazyVStack item.
Scroll it until 5 LazyVStack item. Start scrolling to top. It blinks and show incorrect count: you see that it shows 1 item in line, but it is impossible. If you continue scrolling app crashes.
I have a class that I cannot change to ObservableObject with Published members.
I tried getting around this by writing my own Binding. Although the value is updated correctly, the UI is not. Why is this.
Below is a simple demo view. When it is run and the toggle is clicked, it will print out correctly that the value is changed, but the UI does not update. Why?
import SwiftUI
class BoolWrapper {
public var value = false {
didSet {
print("Value changed to \(value)")
}
}
}
let boolWrapper = BoolWrapper()
struct ContentView: View {
var body: some View {
Toggle(isOn: Binding(get: {
return boolWrapper.value
}, set: { value in
boolWrapper.value = value
}), label: { Text("Toggle") })
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
while resizing screen on mac, start getting this weird error
[API] cannot add handler to 3 from 3 - dropping
All lazyVgrids fail to show afterwards then app crashes if you keep resizing.
This error started with macOS Ventura.
Any help much appreciated.
I have a project that requires a fixed window size. In previous versions of Xcode when I compile the project with the following :
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.frame(width: 800, height: 600)
}
}
}
It will result in a window with a fixed size of 800x600 (i.e. the window inherits the fixed content size)
With Xcode 14 and macOS Ventura, this is no longer the case. The above code compiles but now the window is resizable, with the content inhabiting an 800x600 area.
In Ventura there is the .windowResizability(.contentSize) property but this is macOS 13 only. I need my app to be able to support macOS 11 and 12 and now the window behaviour is broken with the latest Xcode.
Is there any way to get around this that doesn't involve running a seperate macOS 12/Xcode 13 environment?
Hello all,
In a SwiftUI List, when a row is selected, a blue selection is drawn in the selection, and foreground Text with the default primary color is automatically made white. For other views with custom colors, I'd like to be able to make sure they become tinted white to match the system apps. For example, see the blue dot on the selected row:
Example code:
List(selection: $selection) {
ForEach(0..<4) { index in
HStack {
Image(systemName: "circle.fill")
.foregroundColor(.blue)
Text("Test")
}
.tag(index)
}
}
With NSTableCellView, there is the backgroundStyle property. I've searched all of the available environment variables, and couldn't find anything appropriate. I have also tried manually including an isSelected binding on a view for each row, but the selection binding is not updated by List until mouse-up, while the highlight is updated on mouse-down and drag, so this results in a flickery appearance and is not right either.
Any tips on how to achieve the correct result here? Thanks! 🙏
I'm using Xcode 14.1 to start a Core Data project. I created a new Project, checking CoreData. The resulting program works in Preview and in the Simulator.
I've changed the data from a Item/timestamp to Locations/title. I plan to add more Attributes but that's for later.
I think I've got all the Item instances changed to Locations and timestamp to title. It seems to work OK when in Preview for ContentView.swift but crashes in the Simulator with the error
Swift/UnsafeRawBufferPointer.swift:946: Fatal error: UnsafeRawBufferPointer with negative count
Any suggestions on what I have done wrong? Thanks.
PS, the New Project includes the line Text("Select a location") but Select a location doesn't appear in the Preview.
In my app I try to use SwiftUI's ShareLink to offer sharing of the app's documents.
I followed this video for defining the exported type and the document type.
Unfortunately if I use any ShareLink initializer for sharing Transferable items, the option "save to files" is not offered on the displayed share sheet. (Only "copy" is offered, which works if pasted into the destination directory using the Files app, but that is not an acceptable workaround).
PS: com.example.transferabletestis defined as conforming to com.apple.package
import SwiftUI
import UniformTypeIdentifiers
extension UTType{
static let transferableTest = UTType(exportedAs: "com.example.transferabletest")
}
struct Document:Transferable{
static let filePackageURL = URL.documentsDirectory.appending(components: "0815.transferabletest")
public static var transferRepresentation: some TransferRepresentation {
FileRepresentation(exportedContentType: .transferableTest) { document in
_ = try? FileManager.default.createDirectory(at: Self.filePackageURL, withIntermediateDirectories: false)
FileManager.default.createFile(atPath: Self.filePackageURL.appending(components: "data").path(), contents: "Transferable Test\n".data(using: .utf8))
return SentTransferredFile(Document.filePackageURL)
}
}
}
struct ContentView: View {
var body: some View {
ShareLink("Share as tranferable item", item: Document(), preview: SharePreview("Test"))
}
}
Is this a bug?
What am I doing wrong?
Sharing the document using the ShareLink for URLs does offer "save to files" but I can't use that in my app for various reasons.
There is a conflict when I use selection and onDrag for a list, onDrag blocks the selection on macOS. I think the problem comes from the fact that selection works on mouseDown and the same for onDrag.
So, when the mouseDown event is triggered, swiftUI call the last modifier which is onDrag and it doesn't trigger the selection anymore.
When I check on the Finder app, I noticed that the selection is triggered on mouseUp, which confirms my theory. Moreover, on finder, they combine onDrag, selection, and doubleClick without any conflict. Therefore, I'm pretty sure there is a workaround, but I can't figure it out...
Did anyone already face this issue and found a workaround?
I have app that shows live activity and countdown till a date...
VStack {
Text("Countdown till You finish your homework")
Text(countdownTime, style: .timer)
}
After the time up, the live activity countup, the solution is to update the live activity via backgroundTask and this not always working, really apple sometimes fire the backgroundTask after hours.
Another solution is to set dismissalPolicy: .after(countdownTime), but once I did that the dynamic island not working and the activity status is ended after right calling...
await activity.end(using: state, dismissalPolicy: .after(countdownTime))
Can anyone help please, users feed back is why you we still see the old task on live activity. How come I can not update live activity? and how come if you set dismissalPolicy .after apple changes the activity status to ended and stop showing the dynamic island?
Paging Steve Breen! 😄
I've seen this question asked a zillion times but I've never seen an answer.
Is it possible to configure compositional layout to give you a grid of N columns (say 2 or 3) where each item in each row/group self-size their height, but the heights of those items are then set to be the height of the tallest item in their row.
This is easy to do if you ignore the self-sizing requirement (just use a fixed or absolute item height), but on the surface this doesn't even appear to be possible if you require self-sizing.
What I've Tried
Configuring a layout where the items are set to a fractional height of 1.0 and their group is set to an estimated height (ex: 100). I was hoping compositional layout would interpret this as, "Please self-size the height of the group and make each item 100% of that height." Unfortunately, compositional layout just uses the estimate you provide for the height as the actual height and no self-sizing occurs at all. Sad panda. 🐼
Use visibleItemsInvalidationHandler to attempt to identify which items share a row and reset their heights to be the height of the tallest item in that row. Sadly, the handler doesn't really have access to the data it needs to do this, nor is it allowed to change frames, nor is it called on the first layout pass, nor does it appear to be supported at all for layouts containing estimated items. In fact, if you try to use it with layouts that support self-sizing, you'll get this error message:
[UICompositionalLayout] note: the section invalidation handler cannot currently mutate visible items for layouts containing estimated items. Please file an enhancement request on UICollectionView.
Wishing upon a star. Oh, and I also filed a radar asking: FB11776888
Here's a visual aid:
I have a little test program as well, but unfortunately I can't upload it here. Happy to share if it would be helpful. Here are a couple snippets:
#1
// This doesn't work
private func makeLayout1() -> UICollectionViewCompositionalLayout {
// Item
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.5), heightDimension: .fractionalHeight(1))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
// Group
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(100))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, repeatingSubitem: item, count: 2)
group.interItemSpacing = .fixed(10)
// Section
let section = NSCollectionLayoutSection(group: group)
return UICollectionViewCompositionalLayout(section: section)
}
#2
// This self-sizes the heights of the items, but allows the items in each row to be different heights rather than providing any way to constrain them to the height of the tallest self-sized item in each row
private func makeLayout2() -> UICollectionViewCompositionalLayout {
// Item
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.5), heightDimension: .estimated(100))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
// Group
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(100))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, repeatingSubitem: item, count: 2)
group.interItemSpacing = .fixed(10)
// Section
let section = NSCollectionLayoutSection(group: group)
return UICollectionViewCompositionalLayout(section: section)
}
Options?
My guess is that compositional layout simply doesn't support layouts that require a "partial second pass" per group, where the frames of the items can be updated based on information collected during self-sizing the other items in the group (to, for example, force them all to a common height, or align them top/bottom/centered within their group).
If that's the case (not supported), I would love a suggestion for where I might override the layout to provide this capability.
Thank you! ❤️
Before iOS 16.1 my app was woking good, if the user set the app language to other language than his device language, my app, widget + extensions all use this language...
After iOS 16.1 if user set the app language to other language than his device language, my app works with this language but the widget + extensions works with the device language, not my app language...
For Example:
@Environment(\.locale.languageCode) private var userLocal
before iOS 16.1 userLocal would be the app local, after iOS 16.1 it return the device local
Any idea why Apple did that? is this a bug?
How to set the widget language to match my app language now? even set .environment(\.locale, dose not work when use Strings(table: because it's still get the bundle that match device language.
I am new to Swift and iOS development. I am trying to wrap a web app where the orientation is dependent on the URL. I have the code working with Stack Overflow as an example where "https://stackoverflow.com" displays in portrait and all other pages change to landscape after being loaded. I have a URL observer that triggers when the URL changes and calls requestGeometryUpdate. I'm running into the following problem:
When changing the orientation with requestGeometryUpdate, the orientation changes, but if the device is physically rotated after the change, the orientation changes again. I would like to make the orientation change locked and permanent until a new page is loaded.
Any help would be much appreciated. My code is below:
import SwiftUI
import WebKit
struct TestView: View {
private let urlString: String = "https://stackoverflow.com/"
var body: some View {
TestWebView(url: URL(string: urlString)!)
.background(Color.black)
.scrollIndicators(.hidden)
.ignoresSafeArea([.all])//stretchs webview over notch on iphone
.defersSystemGestures(on:.bottom)//deprioritizes multitasking indicator
.statusBar(hidden: true)//hides time and battery
}
}
class TestController: UIViewController {
var webview: WKWebView!
var webViewURLObserver: NSKeyValueObservation?
override func viewDidLoad() {
super.viewDidLoad()
let winScene = UIApplication.shared.connectedScenes.first
let windowScene = winScene as! UIWindowScene
webview = WKWebView(frame: self.view.frame)
webview.autoresizingMask = [.flexibleWidth,.flexibleHeight]//makes webview fit screen in portrait and landscape
self.view.addSubview(self.webview)
webViewURLObserver = self.webview.observe(\.url, options: .new) { webview, change in
let url=change.newValue!!;//! converts from optional to string
print(url)
let arr = url.absoluteString.split(separator: "stackoverflow.com").map(String.init)
var portrait=false
if(arr.count>1){
let path = arr[1];
if path=="/"{
portrait=true
}
}
if portrait==true {
windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: .portrait)) { error in print(error)}
}
else{
windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: .landscape)) { error in print(error)}
}
self.setNeedsUpdateOfSupportedInterfaceOrientations()
}
}
}
// WebView Struct
struct TestWebView: UIViewControllerRepresentable {
let url: URL
func makeUIViewController(context: Context) -> TestController {
let webviewController = TestController()
return webviewController
}
func updateUIViewController(_ webviewController: TestController, context: Context) {
let request = URLRequest(url: url)
webviewController.webview.scrollView.contentInsetAdjustmentBehavior = .never
webviewController.webview.load(request)
}
}
struct TestView_Previews: PreviewProvider {
static var previews: some View {
TestView()
}
}
Any one getting any issues with NavigaitonLink to seemingly innocuous views freezing when tapped on? 1 CPU at 100% memory steadily increasing until app gets killed by the system. Will freeze if any NavigationLink on the view is tapped if certain views are linked to using NavigaitonLink.
I note some people have been getting similar freezes if they use @AppStorage, but I'm not using @AppStorage. I do use CoreData tho. tho I have some views that use core data that don't freeze.
https://developer.apple.com/forums/thread/708592?page=1#736374022
has anyone experienced similar issues? or know the cause. it doesn't seem to be any of my code because if I pause the debugger it stops on system code.
Hi!
I have two problems with FileImport and FileExporter
Every time the file modal has been closed I get in the console this error/warning
[DocumentManager] The view service did terminate with error: Error Domain=_UIViewServiceErrorDomain Code=1 "(null)" UserInfo={Terminated=disconnect method}
The modal for FileExporter shows the label "Move", why? I'm creating a new file, not moving an existing one, since there is already the modifier FileMover. Is it correct? Can't be confusing for a user to see the label "Move"? Am I using it in the wrong way?
Can please someone help me with these two problems?
In a SwiftUI project I try to display a background image with ignoring safe area insets (to make it go edge to edge). However, the background scales incorrectly and doesn't respect its aspect ratio.
Here is a small code example of the view structure that I'm using:
struct ContentView: View {
var body: some View {
ZStack {
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.").padding()
}.frame(maxHeight: .infinity).background(Image("dots").resizable().ignoresSafeArea().scaledToFill())
}
}
And an example image for testing (when using this image you can clearly see the circles become more like ovals in the SwiftUI app):
Screenshot:
The following code works:
struct SelectBatteryChemistryView: View {
@ObservedObject var model: SelectBatteryChemistryViewModel = .init()
@Environment(\.presentationMode) private var presentationMode
var body: some View {
VStack {
Spacer()
TitleText("BATTERY MODE")
SimpleModeSelectorView(
selected: $model.batteryChemistry
)
.pickerStyle(.inline)
.frame(minHeight: 300)
PrimaryTitleButton(title: "SELECT") {
if model.batteryChemistry == .user {
model.customChemistryFlow = true
} else {
model.confirmBatterySettings()
}
}
NavigationLink(
destination: CustomBatteryChemistryView(),
isActive: $model.customChemistryFlow
) { EmptyView() }
.isDetailLink(false)
}
.onReceive(model.$batterySettingsConfirmed) { batterySettingsConfirmed in
if batterySettingsConfirmed {
//dismiss()
}
}
.onAppear() {
model.customChemistryFlow = false
}
}
}
The following code causes an infinite loop in the CustomBatteryChemistryView() initialiser.
struct SelectBatteryChemistryView: View {
@ObservedObject var model: SelectBatteryChemistryViewModel = .init()
@Environment(\.dismiss) private var dismiss
var body: some View {
VStack {
Spacer()
TitleText("BATTERY MODE")
SimpleModeSelectorView(
selected: $model.batteryChemistry
)
.pickerStyle(.inline)
.frame(minHeight: 300)
PrimaryTitleButton(title: "SELECT") {
if model.batteryChemistry == .user {
model.customChemistryFlow = true
} else {
model.confirmBatterySettings()
}
}
NavigationLink(
destination: CustomBatteryChemistryView(),
isActive: $model.customChemistryFlow
) { EmptyView() }
.isDetailLink(false)
}
.onReceive(model.$batterySettingsConfirmed) { batterySettingsConfirmed in
if batterySettingsConfirmed {
//dismiss()
}
}
.onAppear() {
model.customChemistryFlow = false
}
}
}
Adding the @Environment(.dismiss) object prevents the use of a navigation link. The program sits there with the stack infinitely calling the getter for the NavigationLink.
It looks like an infinite loop on the accessor due to some strangeness related to the magic of the Dismiss environment object.
How do we pass this on to the Dev team at Apple?
The standard Command-A keyboard shortcut in a UITextView is broken in Mac Catalyst 16/ Ventura with either TextKit 2 or TextKit 1 for long texts.
In iOS 16 the selection is instant but on MacOS with Catalyst a beachball is displayed for more than 50 seconds and the app consumes gigabytes of memory.
Earlier versions of Mac Catalyst work fine.
To duplicate this just create a small storyBoard app with an editable UITextView and paste a long document around 1Mb then use the standard Select All Command either from the keyboard or the app menu.
l I use Tale of Two Cities which is about 800k to test in my app.
Is there any workaround for this?
I made a test with a new XIB-based project using this code
func applicationDidFinishLaunching(_ aNotification: Notification) {
guard let content = window.contentView else {
print("Error: cannot access windows contentview!")
return
}
let tv = NSTextView(frame: NSMakeRect(100, 300, 200, 40))
tv.string = "Text subview"
tv.font = NSFont.systemFont(ofSize: 30.0)
content.addSubview(tv)
let chartView = NSHostingView(rootView: myChart())
chartView.setFrameSize(content.frame.size)
content.addSubview(chartView)
content.printView(self)
}
"myChart" is s sample view using Charts.
The window does show the text and the chart but the print shows the text only.
How can I get the SwiftUI-View printed?
My goal is a PDF output of a SwiftUI view.
There are already several older threads with similar questions but no solution, yet.