At this line of code (SketchTextSelectionManager.swift:449), sometimes there will be crashes based on crashlytics reports.
let selection = pdfPage.selectionForWord(at: location)
This is directly calling into PDFKit's PDFPage#selection method: https://developer.apple.com/documentation/pdfkit/pdfpage/selectionforword(at:)
Attached the full stacktrace:
Crashed: com.apple.root.user-initiated-qos.cooperative
0 CoreGraphics 0x30c968 PageLayout::getWordRange(unsigned long, long) const + 908
1 CoreGraphics 0x30bbc0 PageLayout::getTextRangeIndex(CGPoint, CGPDFSelectionType, SelectionPrecision) const + 2292
2 CoreGraphics 0x44a53c CGPDFSelectionCreateBetweenPointsWithOptions + 384
3 PDFKit 0x8d5f8 -[PDFPage selectionFromPoint:toPoint:type:] + 168
4 PDFKit 0x92040 -[PDFPage _rvItemAtPoint:] + 64
5 PDFKit 0x91f4c -[PDFPage rvItemAtPoint:] + 84
6 PDFKit 0x8caa8 -[PDFPage selectionForWordAtPoint:] + 40
7 MyApp 0x8420e0 closure #1 in SketchTextSelectionManager.startNewTextSelection(pageId:location:) + 449 (SketchTextSelectionManager.swift:449)
8 MyApp 0x841a70 SketchTextSelectionManager.startNewTextSelection(pageId:location:) + 205 (CurrentNoteManager.swift:205)
9 libswift_Concurrency.dylib 0x61104 swift::runJobInEstablishedExecutorContext(swift::Job*) + 252
10 libswift_Concurrency.dylib 0x63a28 (anonymous namespace)::ProcessOutOfLineJob::process(swift::Job*) + 480
11 libswift_Concurrency.dylib 0x611c4 swift::runJobInEstablishedExecutorContext(swift::Job*) + 444
12 libswift_Concurrency.dylib 0x62514 swift_job_runImpl(swift::Job*, swift::SerialExecutorRef) + 144
13 libdispatch.dylib 0x15d8c _dispatch_root_queue_drain + 392
14 libdispatch.dylib 0x16590 _dispatch_worker_thread2 + 156
15 libsystem_pthread.dylib 0x4c40 _pthread_wqthread + 228
16 libsystem_pthread.dylib 0x1488 start_wqthread + 8
```
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
At this line of code (SketchTextSelectionManager.swift:378), sometimes there will be crashes based on crashlytics reports. In the reports, it seems like this only happens for RTL text range.
let selection = pdfPage.selection(
from: CGPoint(x: fromStart.x + 1, y: fromStart.y - 1),
to: CGPoint(x: toEnd.x - 1, y: toEnd.y + 1)
)
This is directly calling into PDFKit's PDFPage#selection method: https://developer.apple.com/documentation/pdfkit/pdfpage/selection(from:to:)
Attached the full stacktrace:
Crashed: com.apple.root.user-initiated-qos.cooperative
0 CoreGraphics 0x30598c PageLayout::convertRTLTextRangeIndexToStringRangeIndex(long) const + 156
1 CoreGraphics 0x44c3f0 CGPDFSelectionCreateBetweenPointsWithOptions + 224
2 PDFKit 0x91d00 -[PDFPage selectionFromPoint:toPoint:type:] + 168
3 MyApp 0x841044 closure #1 in SketchTextSelectionManager.handleUserTouchMoved(_:) + 378 (SketchTextSelectionManager.swift:378)
4 MyApp 0x840cb0 SketchTextSelectionManager.handleUserTouchMoved(_:) + 205 (CurrentNoteManager.swift:205)
5 libswift_Concurrency.dylib 0x60f5c swift::runJobInEstablishedExecutorContext(swift::Job*) + 252
6 libswift_Concurrency.dylib 0x63a28 (anonymous namespace)::ProcessOutOfLineJob::process(swift::Job*) + 480
7 libswift_Concurrency.dylib 0x6101c swift::runJobInEstablishedExecutorContext(swift::Job*) + 444
8 libswift_Concurrency.dylib 0x62514 swift_job_runImpl(swift::Job*, swift::SerialExecutorRef) + 144
9 libdispatch.dylib 0x15ec0 _dispatch_root_queue_drain + 392
10 libdispatch.dylib 0x166c4 _dispatch_worker_thread2 + 156
11 libsystem_pthread.dylib 0x3644 _pthread_wqthread + 228
12 libsystem_pthread.dylib 0x1474 start_wqthread + 8
It appears that on all recent versions of macOS when adding a new InputSource in /Library/Input Methods (or modifying an existing one there) the user needs to logoff and log back in in order for Keyboard/Input Sources in System Settings and Input Menu in menu bar to pick up the changes.
Is there a way to avoid this? That is, some notification to send or API to call to tell both of these "hey, things might have changed on disk, please re-read the info, and update the UI". 🙂
I have an attributedString with 100 NSTextAttachments(contains image of 400kb). When i scroll the textview, it is lagging, When i did the same in textkit 1, it is butter smooth. It can be because of how textkit 1 & 2 layout the elements.
let attachment = NSTextAttachment()
attachment.image = UIImage(named: "image2")
let attachmentString = NSAttributedString(attachment: attachment)
let mutableAttributedString = NSMutableAttributedString(attributedString: textView.attributedText)
for _ in 0...100 {
mutableAttributedString.append(NSAttributedString(string: "\n"))
mutableAttributedString.append(attachmentString)
}
textView.attributedText = mutableAttributedString
How to handle images in textkit 2 so that it feels smooth while scrolling textview?
I am running into an issue where two distinct bool bindings are both being toggled when I toggle only one of them. My component looks like
VStack {
Checkbox(label: "Checkbox 1", isOn: $stateVar1)
Checkbox(label: "Checkbox 2", isOn: $stateVar2)
}
where my CheckBox component looks like
struct Checkbox: View {
let label: String
@Binding var isOn: Bool
var body: some View {
Button {
isOn.toggle()
} label: {
HStack {
Image(systemName: isOn ? "checkmark.square" : "square")
Text(label)
}
.foregroundStyle(.black)
}
}
}
If I click on one checkbox, both of them get toggled. However, if I simply remove the checkboxes from the VStack, then I am able to toggle them both independently. I believe this is a bug with bool Bindings, but if anyone can point out why I am mistaken that would be much appreciated :)
(NOTE: In sum, this is destructive of user data.)
The client is a professor of Classics in constant need of properly-rendered glyphs that represent legitimate code points. As an example, the correct spelling might be:
εὔτρητος
It is spelled and rendered as intended. A file by this name will be correctly spelled by ls in the Terminal. Note that two diacritics are applied to the second letter, an upsilon (ὔ)
However, the Finder displays that file as
ἐύτρητος
and iterating the string reveals that the accents are improperly distributed over the two. This would never be correct.
This handicaps digital-humanities researchers from college to postdoctoral work.
A Character by Character iteration demonstrates the mangling.:
intended (εὔτρητος)
displayed (ἐύτρητος)
3B5 (ε) 1F10 (ἐ)
GREEK SMALL LETTER EPSILON,
GREEK SMALL LETTER EPSILON WITH PSILI
1F54 (ὔ) 3CD (ύ)
GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA
GREEK SMALL LETTER UPSILON WITH TONOS
3C4 (τ) 3C4 (τ)
(back in sync)
3C1 (ρ) 3C1 (ρ)
3B7 (η) 3B7 (η)
3C4 (τ) 3C4 (τ)
3BF (ο) 3BF (ο)
3C2 (ς) 3C2 (ς)
I don't want to muddy the waters by guessing where and how the mistake is made, just see for yourself.
Is there some reason UIKit's and AppKit's animate(with:changes:completion:) methods are marked deprecated in iOS 18 when they were also first made available in iOS18? If they are indeed already deprecated, is there a replacement method we are supposed to use? This method allows the developer to use SwiftUI animations to animate UIKit and AppKit views.
I used the Multipeer Connectivity Framework to allow players of my game app to see the highest score along with their own score as the game progresses. It works fine running in 3 or 4 simulators in Xcode. However, I was just told by two Apple support reps that bluetooth connectivity is not allowed between two Apple devices, other than for watches, AirPods, headphones, etc.
My question is: can two iPhones or iPads connect for peer-to-peer play? Can they play offline? If the answer is yes to either or both of those questions, how do I get that to happen since I get an error message when trying to connect two iPhones via bluetooth even though they can see each other in the Other Devices list?
If the answer is no, then why does Apple provide a Multipeer Connectivity Framework and simulate that type of device to device connection with the Xcode simulators?
I am making a SwiftUI Mac app that uses navigation split view and the Observation framework. The split view has a sidebar list, a detail view, and a selection property to store the selected item in the list. I set the initial selection to the first item in the list using the .onAppear modifier.
When I select an item from the list, I get the desired behavior. The detail view shows the contents of the selected item. But the selection property’s value changes to nil. Because selection is nil, I am unable to remove items from the list.
Model Code
struct Wiki {
var pages: [Page] = []
}
@Observable
class Page: Identifiable, Equatable, Hashable {
let id = UUID()
var title: String = "Page"
var text: String
static func == (lhs: Page, rhs: Page) -> Bool {
lhs.id == rhs.id
}
func hash(into hasher: inout Hasher) {
hasher.combine(id)
hasher.combine(title)
hasher.combine(text)
}
}
Split View Code
struct ContentView: View {
@Binding var wiki: Wiki
@State private var selection: Page? = nil
var body: some View {
NavigationSplitView {
PageList(wiki: $wiki, selection: $selection)
.navigationSplitViewColumnWidth(ideal: 192)
} detail: {
if let selection {
PageView(page: selection)
} else {
Text("Select a page to view its contents.")
}
}
.onAppear {
selection = wiki.pages.first
}
}
}
List Code
struct PageList: View {
@Binding var wiki: Wiki
@Binding var selection: Page?
var body: some View {
VStack {
Text("Pages")
.font(.title)
List($wiki.pages, selection: $selection) { $page in
NavigationLink {
PageView(page: page)
} label: {
TextField("", text: $page.title)
}
}
.padding()
}
}
}
Detail View Code
struct PageView: View {
@Bindable var page: Page
var body: some View {
TextEditor(text: $page.text)
}
}
I tried changing selection in the list view from @Binding to @Bindable, but I get the following build error:
'init(wrappedValue:)' is unavailable: The wrapped value must be an object that conforms to Observable
What fix do I have to make to get the selection property to not be nil when I select an item from the list?
Issue:- The characters in SearchController SearchBar are overlapping on focusing.
Steps:-
Select the System language as Arabic
Launch the tvOS app
Set the app language as English in the tvOS app
Focus on SearchController SearchBar
Focus on any characters there you can see overlapping issue.
Cell Registration
lazy var headerCell: UICollectionView.SupplementaryRegistration<UICollectionReusableView> = .init(elementKind: UICollectionView.elementKindSectionHeader) { supplementaryView, elementKind, indexPath in }
and
Cell Dequeue
datasource.supplementaryViewProvider = { [weak self] collectionView, kind, indexPath in return collectionView.dequeueConfiguredReusableSupplementary(using: headerCell, for: indexPath) }
I am registering a collectionview cell or collwctionview reusable view as lazy variable. It causes a crash like
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Attempted to dequeue a supplementary view using a registration that was created inside -collectionView:viewForSupplementaryElementOfKind:atIndexPath: or inside a UICollectionViewDiffableDataSource supplementary view provider. Creating a new registration each time a supplementary view is requested will prevent reuse and cause created supplementary views to remain inaccessible in memory for the lifetime of the collection view. Registrations should be created up front and reused. Registration: <UICollectionViewSupplementaryRegistration: 0x600001798a00>
I'm working on the control widget which should display the SF image on the UI, but I have found that it cannot be displayed stably. I have three ExampleControlWidget which is about the type egA egB and egC, it should all be showed but now they only show the text and placeholder. I'm aware of the images should be SF image and I can see them to show perfectly sometimes, but in other time it is just failed. This's really confused me, can anyone help me out?
public enum ControlWidgetType: Sendable {
case egA
case egB
case egC
public var imageName: String {
switch self {
case .egA:
return "egA"
case .egB:
return "egB"
case .egC:
return "egC"
}
}
}
struct ExampleControlWidget: ControlWidget {
var body: some ControlWidgetConfiguration {
AppIntentControlConfiguration(
kind: kind,
provider: Provider()
) { example in
ControlWidgetToggle(
example.name,
isOn: example.state.isOn,
action: ExampleControlWidgetIntent(id: example.id),
valueLabel: { isOn in
ExampleControlWidgetView(
statusText: isOn ? Localization.on.text : Localization.off.text,
bundle: bundle,
widgetType: .egA //or .egB .egC
)
.symbolEffect(.pulse)
}
)
.disabled(example.state.isDisabled)
}
.promptsForUserConfiguration()
}
}
public struct ExampleControlWidgetView: View {
private let statusText: String
private let bundle: Bundle
private var widgetType: ControlWidgetType = .egA
public init(statusText: String, bundle: Bundle, widgetType: ControlWidgetType) {
self.statusText = statusText
self.bundle = bundle
self.widgetType = widgetType
}
public var body: some View {
Label(
statusText,
image: .init(
name: widgetType.imageName,
// the SF Symbol image id bundled in the Widget extension
bundle: bundle
)
)
}
}
This is the normal display:
These are the display that do not show properly:
The results has no rules at all, I have tried to completely uninstall the APP and reinstall but the result is same.
I config of an alternate icon on the App Store Connect product page optimization. After the app launches, can I retrieve the name of this configured icon through UIApplication.shared.alternateIconName?
When a ScrollView or List is nested in a TabView, you can press on the tab button and the scroll view will scroll to top.
import SwiftUI
struct SwiftUIView: View {
let items = (1...100).map { "Item \($0)" }
var body: some View {
TabView {
Tab("home", systemImage: "house") {
ScrollView {
ForEach(items, id: \.self) { item in
Text(item)
.frame(maxWidth: .infinity, alignment: .center)
}
}
}
}
}
}
#Preview {
SwiftUIView()
}
But if we add a background to the ScrollView, the scroll to top gesture breaks.
import SwiftUI
struct SwiftUIView: View {
let items = (1...100).map { "Item \($0)" }
var body: some View {
TabView {
Tab("home", systemImage: "house") {
ScrollView {
ForEach(items, id: \.self) { item in
Text(item)
.frame(maxWidth: .infinity, alignment: .center)
}
}
// Set background on ScrollView.
.background(Color.red)
}
}
}
}
#Preview {
SwiftUIView()
}
I made a similar post on StackOverflow, but haven't been able to find a proper solution.
This feels like a bug of some sort in SwiftUI.
I'm trying to make a timetable app for my Apple Watch, and it has all actually been going pretty smoothly until this random error started showing up when I try to build my application. Here's a code snippet:
// all on top level:
class globalStorage {
static let shared = globalStorage() // line 27
@State @AppStorage(runningKey) var termRunningGB = false
@State @AppStorage(ghostWeekKey) var ghostWeekGB = false
@State @AppStorage(startDateKey) var startDateGB = Date.now
var currentCourse: Course = getCurrentClass(date: .now)
}
let storage = globalStorage.shared // << ERRORING HERE (line
// ...
@main
struct myApp: App { /* ... */ }
Can anybody tell me what is happening? (And, of course, how to fix it?)
Furthermore, upon removing the offending line (let storage = globalStorage.shared) (and replacing all callers of said variable with 'globalStorage.shared' to bypass the variable) the error has decided to settle on line 27, where i define the 'shared' thing in the class.
[ I just went back to try more solutions, I have resolved it but forgot to give my solution here. Now I've forgotten how I fixed it. I do know that I moved currentCourse out of the class, that most likely was it I think.]
All of this code is on GitHub: https://github.com/the-trumpeter/Timetaber-for-iWatch
I've encountered an issue where using @Observable in SwiftUI causes extra initializations and deinitializations when a reference type is included as a property inside a struct. Specifically, when I include a reference type (a simple class Empty {}) inside a struct (Test), DetailsViewModel is initialized and deinitialized twice instead of once. If I remove the reference type, the behavior is correct.
This issue does not occur when using @StateObject instead of @Observable. Additionally, I've submitted a feedback report: FB16631081.
Steps to Reproduce
Run the provided SwiftUI sample code (tested on iOS 18.2 & iOS 18.3 using Xcode 16.2).
Observe the console logs when navigating to DetailsView.
Comment out var empty = Empty() in the Test struct.
Run again and compare console logs.
Change @Observable in DetailsViewModel to @StateObject and observe that the issue no longer occurs.
Expected Behavior
The DetailsViewModel should initialize once and deinitialize once, regardless of whether Test contains a reference type.
Actual Behavior
With var empty = Empty() present, DetailsViewModel initializes and deinitializes twice. However, if the reference type is removed, or when using @StateObject, the behavior is correct (one initialization, one deinitialization).
Code Sample
import SwiftUI
enum Route {
case details
}
@MainActor
@Observable
final class NavigationManager {
var path = NavigationPath()
}
struct ContentView: View {
@State private var navigationManager = NavigationManager()
var body: some View {
NavigationStack(path: $navigationManager.path) {
HomeView()
.environment(navigationManager)
}
}
}
final class Empty { }
struct Test {
var empty = Empty() // Comment this out to make it work
}
struct HomeView: View {
private let test = Test()
@Environment(NavigationManager.self) private var navigationManager
var body: some View {
Form {
Button("Go To Details View") {
navigationManager.path.append(Route.details)
}
}
.navigationTitle("Home View")
.navigationDestination(for: Route.self) { route in
switch route {
case .details:
DetailsView()
.environment(navigationManager)
}
}
}
}
@MainActor
@Observable
final class DetailsViewModel {
var fullScreenItem: Item?
init() {
print("DetailsViewModel Init")
}
deinit {
print("DetailsViewModel Deinit")
}
}
struct Item: Identifiable {
let id = UUID()
let value: Int
}
struct DetailsView: View {
@State private var viewModel = DetailsViewModel()
@Environment(NavigationManager.self) private var navigationManager
var body: some View {
ZStack {
Color.green
Button("Show Full Screen Cover") {
viewModel.fullScreenItem = .init(value: 4)
}
}
.navigationTitle("Details View")
.fullScreenCover(item: $viewModel.fullScreenItem) { item in
NavigationStack {
FullScreenView(item: item)
.navigationTitle("Full Screen Item: \(item.value)")
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("Cancel") {
withAnimation(completionCriteria: .logicallyComplete) {
viewModel.fullScreenItem = nil
} completion: {
var transaction = Transaction()
transaction.disablesAnimations = true
withTransaction(transaction) {
navigationManager.path.removeLast()
}
}
}
}
}
}
}
}
}
struct FullScreenView: View {
@Environment(\.dismiss) var dismiss
let item: Item
var body: some View {
ZStack {
Color.red
Text("Full Screen View \(item.value)")
.navigationTitle("Full Screen View")
}
}
}
Console Output
With var empty = Empty() in Test
DetailsViewModel Init
DetailsViewModel Init
DetailsViewModel Deinit
DetailsViewModel Deinit
Without var empty = Empty() in Test
DetailsViewModel Init
DetailsViewModel Deinit
Using @StateObject Instead of @Observable
DetailsViewModel Init
DetailsViewModel Deinit
Additional Notes
This issue occurs only when using @Observable. Switching to @StateObject prevents it. This behavior suggests a possible issue with how SwiftUI handles reference-type properties inside structs when using @Observable.
Using a struct-only approach (removing Empty class) avoids the issue, but that’s not always a practical solution.
Questions for Discussion
Is this expected behavior with @Observable?
Could this be an unintended side effect of SwiftUI’s state management?
Are there any recommended workarounds apart from switching to @StateObject?
Would love to hear if anyone else has run into this or if Apple has provided any guidance!
In the past I've used #if available to isolate functionality gaps at the code level in my apps.
But yesterday I was trying to integrate the new methods Apple has made available for granting access to contacts, as discussed here: https://developer.apple.com/documentation/contacts/accessing-a-person-s-contact-data-using-contacts-and-contactsui
The problem is that their example is rife with code that won't compile for iOS 17, which is still (from the last stats I found) 20% of the user base.
I also experimented with @available; but when I was nearly done integrating the new methods, a compiler bug halted my entire project. It now simply doesn't build (the ol' non-zero exit code) with no further details or errors flagged. I filed a report, as requested in the logs.
In the meantime, I have to start over. What is the recommended method for isolating large blocks of functionality that are only available to a later OS version?
Hi,
We have received reports about crash when creating a UIButton:
let button = UIButton(type: .infoLight)
The exception is bad access:
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000074
Exception Codes: 0x0000000000000001, 0x0000000000000074
VM Region Info: 0x74 is not in any region. Bytes before following region: 4298211212
REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL
UNUSED SPACE AT START
--->
__TEXT 100318000-100324000 [ 48K] r-x/r-x SM=COW /var/containers/Bundle/Application/E8912E1B-FFD8-49AF-A78A-7AA8805FDB95/My App/My App
Termination Reason: SIGNAL 11 Segmentation fault: 11
Terminating Process: exc handler [550]
and the main thread is crashing with the following stack trace:
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 UIKitCore 0x197e27a58 ____UIKitSharedArtworkManager_block_invoke + 116
1 libdispatch.dylib 0x19cfe2fa8 _dispatch_client_callout + 20
2 libdispatch.dylib 0x19cfe47f4 _dispatch_once_callout + 32
3 UIKitCore 0x197c3bb10 __UIKitSharedArtworkManager + 64
4 UIKitCore 0x197c3b5b0 _UIImageWithNameAndTraitCollection + 172
5 UIKitCore 0x197cbc180 _UIImageWithName + 44
6 UIKitCore 0x197c3be80 +[UIImage _systemImageNamed:fallback:withConfiguration:] + 132
7 UIKitCore 0x197a8c550 +[UIButton _defaultImageForType:andState:withConfiguration:] + 360
8 UIKitCore 0x197c1bc38 +[UIButton buttonWithType:] + 124
9 MapboxMaps 0x105f23fdc InfoButtonOrnament.init() + 400
10 MapboxMaps 0x105f2424c @objc InfoButtonOrnament.init() + 20
11 MapboxMaps 0x105fd8d80 MapView.setupManagers() + 1476
12 MapboxMaps 0x105fd8788 MapView.commonInit(mapInitOptions:overridingStyleURI:) + 1284
13 MapboxMaps 0x105fe2bcc specialized MapView.init(frame:mapInitOptions:) + 1500
14 MapboxMaps 0x105fd78cc MapView.init(frame:mapInitOptions:) + 20
15 mapbox_maps_flutter 0x10858c1dc MapboxMapController.init(withFrame:mapInitOptions:channelSuffix:registrar:pluginVersion:eventTypes:) + 496
16 mapbox_maps_flutter 0x10858f274 specialized MapboxMapFactory.create(withFrame:viewIdentifier:arguments:) + 2312
17 mapbox_maps_flutter 0x10858e8e8 @objc MapboxMapFactory.create(withFrame:viewIdentifier:arguments:) + 128
18 Flutter 0x10a99eb88 0x10a980000 + 125832
19 Flutter 0x10af474bc 0x10a980000 + 6059196
20 Flutter 0x10a9c3d38 0x10a980000 + 277816
21 libdispatch.dylib 0x19cfe1248 _dispatch_call_block_and_release + 32
22 libdispatch.dylib 0x19cfe2fa8 _dispatch_client_callout + 20
23 libdispatch.dylib 0x19cff1a34 _dispatch_main_queue_drain + 984
24 libdispatch.dylib 0x19cff164c _dispatch_main_queue_callback_4CF + 44
25 CoreFoundation 0x19529abcc __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16
26 CoreFoundation 0x1952971c0 __CFRunLoopRun + 1996
27 CoreFoundation 0x1952e9284 CFRunLoopRunSpecific + 588
28 GraphicsServices 0x1e25554c0 GSEventRunModal + 164
29 UIKitCore 0x197e32674 -[UIApplication _run] + 816
30 UIKitCore 0x197a58e88 UIApplicationMain + 340
31 My App 0x1003244e8 main + 64
32 dyld 0x1bb541de8 start + 2724
Has anyone experienced this? Could it be a bug in UIKit?
Cheers,
Roman Laitarenko
A few days ago scanning NFC tags or QR codes for AppClips with advanced experiences started showing the error "The operation couldn't be completed. (CPSErrorDomain error 2.)" in the AppClip sheet as seen here:
We are providing AppClips to our customers and they trust AppClips to always work, since it is a big part of their business.
Since this is happening at our customers phones and on the phones of their customers, I don't have a sysdiagnose.
I already created a feedback entry about this FB16601674.
We checked everything, our AASA file, the Appstore Experiences.
I see SwiftUI body being repeatedly called in an infinite loop in the presence of Environment variables like horizontalSizeClass or verticalSizeClass. This happens after device is rotated from portrait to landscape and then back to portrait mode. The deinit method of TestPlayerVM is repeatedly called. Minimally reproducible sample code is pasted below.
The infinite loop is not seen if I remove size class environment references, OR, if I skip addPlayerObservers call in the TestPlayerVM initialiser.
import AVKit
import Combine
struct InfiniteLoopView: View {
@Environment(\.verticalSizeClass) var verticalSizeClass
@Environment(\.horizontalSizeClass) var horizontalSizeClass
@State private var openPlayer = false
@State var playerURL: URL = URL(fileURLWithPath: Bundle.main.path(forResource: "Test_Video", ofType: ".mov")!)
var body: some View {
PlayerView(playerURL: playerURL)
.ignoresSafeArea()
}
}
struct PlayerView: View {
@Environment(\.dismiss) var dismiss
var playerURL:URL
@State var playerVM = TestPlayerVM()
var body: some View {
VideoPlayer(player: playerVM.player)
.ignoresSafeArea()
.background {
Color.black
}
.task {
let playerItem = AVPlayerItem(url: playerURL)
playerVM.playerItem = playerItem
}
}
}
@Observable
class TestPlayerVM {
private(set) public var player: AVPlayer = AVPlayer()
var playerItem:AVPlayerItem? {
didSet {
player.replaceCurrentItem(with: playerItem)
}
}
private var cancellable = Set<AnyCancellable>()
init() {
addPlayerObservers()
}
deinit {
print("Deinit Video player manager")
removeAllObservers()
}
private func removeAllObservers() {
cancellable.removeAll()
}
private func addPlayerObservers() {
player.publisher(for: \.timeControlStatus, options: [.initial, .new])
.receive(on: DispatchQueue.main)
.sink { timeControlStatus in
print("Player time control status \(timeControlStatus)")
}
.store(in: &cancellable)
}
}