Hello all,
We got app crashes on dataSource.apply(snapshot, animatingDifferences: false) after refactoring our tableView code to UITableViewDiffableDataSource. This doesn't happen every time.
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
var snapshot = getCurrentSnapshot()
snapshot.deleteItems([...])
snapshot.appendItems([...], toSection: section)
dataSource.apply(snapshot, animatingDifferences: false)
}
And the controller has deallocated before it.
Crash log:
controller (0x110a64800): deallocated
*** Assertion failure in NSInteger _UITableViewRowDataNumberOfRowsInSection(UITableViewRowData *__unsafe_unretained, NSInteger)(), UITableViewRowData.m:1761
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Requested the number of rows for section (4) which is out of bounds.'
*** First throw call stack:
(
0 CoreFoundation 0x0000000180491128 __exceptionPreprocess + 172
1 libobjc.A.dylib 0x000000018008412c objc_exception_throw + 56
2 Foundation 0x0000000180d11770 -[NSMutableDictionary(NSMutableDictionary) classForCoder] + 0
3 UIKitCore 0x0000000185538ad0 -[UITableViewRowData numberOfRowsInSection:] + 260
4 UIKitCore 0x00000001855052f0 -[UITableView _shouldDrawSeparatorAtBottomOfSectionForCellAtIndexPath:] + 152
5 UIKitCore 0x0000000185504dbc -[UITableView _updateSeparatorStateForCell:atIndexPath:] + 100
6 UIKitCore 0x0000000185504cf0 -[UITableView _updateSeparatorStateForVisibleCells] + 188
7 UIKitCore 0x00000001854f4bd0 -[UITableView _updateAnimationDidStopWithOldVisibleViews:finished:context:] + 1108
8 UIKitCore 0x00000001854f2630 __46-[UITableView _updateWithItems:updateSupport:]_block_invoke_4 + 36
9 UIKitCore 0x00000001857fcb1c __UIVIEW_IS_EXECUTING_ANIMATION_COMPLETION_BLOCK__ + 28
10 UIKitCore 0x00000001857fce24 -[UIViewAnimationBlockDelegate _sendDeferredCompletion:] + 100
11 libdispatch.dylib 0x000000010e5100f0 _dispatch_call_block_and_release + 24
12 libdispatch.dylib 0x000000010e51193c _dispatch_client_callout + 16
13 libdispatch.dylib 0x000000010e5215e4 _dispatch_main_queue_drain + 1228
14 libdispatch.dylib 0x000000010e521108 _dispatch_main_queue_callback_4CF + 40
15 CoreFoundation 0x00000001803f1a30 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
16 CoreFoundation 0x00000001803ec148 __CFRunLoopRun + 1936
17 CoreFoundation 0x00000001803eb5a4 CFRunLoopRunSpecific + 572
18 GraphicsServices 0x000000018e9fbae4 GSEventRunModal + 160
19 UIKitCore 0x00000001852f02e4 -[UIApplication _run] + 868
20 UIKitCore 0x00000001852f3f5c UIApplicationMain + 124
21 appName 0x0000000103e8b0dc $s22appNameySpySpys4Int8VGGXEfU_ + 192
22 appName 0x0000000103e8b480 _swift_se0333_UnsafeMutablePointer_withMemoryRebound + 900
23 appName 0x0000000103e8af30 main + 1320
24 dyld 0x000000010e409544 start_sim + 20
25 ??? 0x000000010e61a0e0 0x0 + 4536246496
26 ??? 0xca54000000000000 0x0 + 14579277893705138176
)
libc++abi: terminating due to uncaught exception of type NSException
UIKit
RSS for tagConstruct and manage graphical, event-driven user interfaces for iOS or tvOS apps using UIKit.
Posts under UIKit tag
200 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
So for my project it's a SwiftUI Project however if I Add '@objc' to expose this instance method to Objective-C it doesn't want it for some reason and the other error code is Argument of '#selector' refers to instance method 'refreshWebView' that is not exposed to Objective-C mainly this is the error I need to fix thanks in advance
this code is what's giving me the error
refreshControl.addTarget(self, action: #selector(refreshWebView(_:)), for: UIControl.Event.valueChanged)
this is for a pull to refresh the page
brand new newbie developer to xcode. so im doing an api call and getting back data from a mysql database. in the xcode preview window im getting data, but i cant figure out how to tie it to the screen when going into the simulator. i have screen 1 that i want to click a button to go to screen 2 that displays the data. screen one (home screen) comes up okay. cant quite figure out what im doing wrong here. im thinking its either a class issue or something to do with view or something. not sure. ive tried looking at so many different videos and i cant seem to find my answer. Any help would be appreciated. thank you
View Controller:
import UIKit
//import SwiftUI
let URL_TOURNAMENT_FETCH = "https://www.thesoftball.com/t2g_mobile_app/mobile_api.php"
class ViewController: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
}
@IBAction func onEmailButtonPressed(_ sender: Any)
{
UIApplication.shared.open(URL(string: "mailto:[email]")! as URL, options: [:],completionHandler: nil)
}
/*
@IBAction func FetchTournButton(_ sender: Any) {
UIApplication.shared.open(URL(string: "https://www.thesoftball.com/t2g_mobile_app/mobile_api.php")! as URL, options: [:],completionHandler: nil)
}
*/
@IBAction func ViewTournamentButton(_ sender: Any)
{
// the following is a popup
let alertController = UIAlertController(title: "Welcome to My First App", message: "Hello World", preferredStyle: UIAlertController.Style.alert)
alertController.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
present(alertController, animated: true, completion: nil)
}
@IBAction func account_button_pressed(_ sender: Any)
{
UIApplication.shared.open(URL(string: "https://www.thesoftball.com")! as URL, options: [:],completionHandler: nil)
}
/*
struct viewDidLoadModifier: viewDidLoadModifier
{
@State private var didLoad = false
private let action: (() -> void)?
init(perform action)
{
}
}
*/
}
ContentView (preview works in this)
import SwiftUI
struct ContentView: View {
@StateObject var viewModel = ViewModel()
var body: some View {
NavigationView{
List{
ForEach(viewModel.courses,id: \.self) { tournament in
HStack {
Image("")
.frame(width: 5, height: 120)
.background(Color.orange)
VStack {
Text(tournament.name).bold()
Text(tournament.dates)
Text(tournament.datee)
Text(tournament.location)
// Text(course.location)
// Text(course.message)
// .bold()
}
}
.padding(0)
}
}
.navigationTitle("Tournaments")
// .onAppear { viewModel.fetch()}
.onAppear(perform: viewModel.fetch)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Dear Apple Support Team,
I am currently developing a control in my app that uses UIDatePicker for time input. To ensure that the time display format is consistently in 24-hour notation regardless of the region, I have set the locale of UIDatePicker to ‘systemLocale’.
However, while this worked as expected up to iPadOS15, displaying the time in 24-hour format, it has switched to a 12-hour format from iPadOS16 onwards. I am wondering if there have been any changes in the behavior of UIDatePicker’s locale between the updates from iPadOS15 to iPadOS16?
Additionally, I would like to know if there are any workarounds to this issue that do not involve modifying the program. In other words, is there a way to revert back to the 24-hour format without changing the code?
Any information you could provide on this issue would be greatly appreciated. Thank you for your assistance.
I am trying to configure scenes to capture a redirect URL after a successful login attempt. I am using OAuth code flow. This is the code I have so far:
ios_app.swift
import SwiftUI
@main
struct ios_appApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
let persistenceController = PersistenceController.shared
@StateObject private var authState = AuthState()
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)
.environmentObject(authState)
}
}
}
AppDelegate.swift
import UIKit
import AWSMobileClient
import GoogleSignIn
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
print("AppDelegate: didFinishLaunchingWithOptions")
AWSMobileClient.default().initialize { (userState, error) in
if let userState = userState {
print("UserState: \(userState)")
} else if let error = error {
print("Error initializing AWSMobileClient: \(error.localizedDescription)")
}
}
GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in
if let error = error {
print("Error restoring previous Google Sign-In: \(error.localizedDescription)")
}
}
return true
}
}
SceneDelegate.swift
import UIKit
import SwiftUI
import GoogleSignIn
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
print("SceneDelegate: scene willConnectTo")
guard let windowScene = (scene as? UIWindowScene) else {
print("SceneDelegate: Invalid windowScene")
return
}
let window = UIWindow(windowScene: windowScene)
let contentView = ContentView().environmentObject(AuthState())
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
print("SceneDelegate: window initialized and visible")
}
func sceneDidDisconnect(_ scene: UIScene) {
print("SceneDelegate: sceneDidDisconnect")
}
func sceneDidBecomeActive(_ scene: UIScene) {
print("SceneDelegate: sceneDidBecomeActive")
}
func sceneWillResignActive(_ scene: UIScene) {
print("SceneDelegate: sceneWillResignActive")
}
func sceneWillEnterForeground(_ scene: UIScene) {
print("SceneDelegate: sceneWillEnterForeground")
}
func sceneDidEnterBackground(_ scene: UIScene) {
print("SceneDelegate: sceneDidEnterBackground")
}
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
guard let url = URLContexts.first?.url else {
print("SceneDelegate: No URL found in URLContexts")
return
}
print("SceneDelegate: openURLContexts with URL: \(url)")
if GIDSignIn.sharedInstance.handle(url) {
print("SceneDelegate: Google Sign-In handled URL")
return
}
if url.scheme == "myurlscheme" || (url.scheme == "https" && url.host == "mydomain.com" && url.path == "/mobile-auth-callback") {
print("SceneDelegate: Handling auth response for URL: \(url)")
AuthService.shared.handleOAuthCallback(url: url)
} else {
print("SceneDelegate: URL scheme not handled: \(url.scheme ?? "No scheme")")
}
}
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
print("SceneDelegate: continue userActivity")
if userActivity.activityType == NSUserActivityTypeBrowsingWeb {
if let url = userActivity.webpageURL {
handleUniversalLink(url: url)
}
}
}
private func handleUniversalLink(url: URL) {
print("SceneDelegate: Handling universal link: \(url)")
if url.path.contains("/mobile-auth-callback") {
let queryItems = URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems
let code = queryItems?.first(where: { $0.name == "code" })?.value
if let code = code {
print("SceneDelegate: Received code: \(code)")
AuthService.shared.exchangeCodeForToken(code: code)
} else {
print("SceneDelegate: No code found, handling email/password callback")
AuthService.shared.handleEmailPasswordCallback(url: url)
}
}
}
}
Also introduced this configuration in Info.plist:
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<true/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>ios-app.SceneDelegate</string>
</dict>
</array>
</dict>
</dict>
...Other parameters
</dict>
</plist>
I am using the simulator to launch my app and can see AppDelegate related logs but I am not seeing any SceneDelegate logs (I suppose because it is not being initialized nor called).
I have tried restarting the computer/Xcode, clean and rebuild the application but none of the things I tested work.
Is there any part of my code wrong? Any other idea here?
We want to animate the images using animationImages propery of UIImageView in our app.
There are 45 heif images with dimensions of 1668x2388.
Below is the code i am using to animate images.
let imageViewAnimation = UIImageView()
imgViewAnimation.animationImages = images
imgViewAnimation.animationDuration = 5.0
imgViewAnimation.animationRepeatCount = 1
imgViewAnimation.startAnimating()
Timer.scheduledTimer(withTimeInterval: 5.0 + 0.5, repeats: false) { _ in
DispatchQueue.main.async {
self.showAlert()
}
}
The issue i am facing is, it takes more than 5.0 seconds (animationDuration) to display all the images.
Alert is shown before all the images are shown.
We face this issue only for few sets of images. For some other sets, it is working fine.
Is this issue due to heif images used, or due to memory and CPU load of using large number of images.
As has been posted a number of times, the large title navigation bar only collapses on scrolling for the UIView listed first in an .xib or storyboard file.
In my case, I have an enclosing view containing 2 Views, a TableView and a CollectionView in an .XIB file. This is connected to a UIKit class. Tapping a button switches between the two views. If the TableView is the first view listed, the navigationbar collapses with scrolling but with the CollectionView listed second, the large title navigation bar doesn't collapse with scrolling. Alternatively, if the CollectionView is the first view listed, the navigation bar collapses with scrolling but with the TableView listed second, the large title navigation bar doesn't collapse with scrolling.
I have not been able to figure out a way to enable the collapsable large title navigation bar to work in such a scenario as mine for both views within a container view. Is there a way to do this? I have tested this capability through iOS 17.
I'm working on a UICollectionView that has a custom compositional layout with multiple columns. I wanted to add swipe actions to the cells (specifically, a delete action).
I knew this was possible because of the existence of trailingSwipeActionsConfigurationProvider but I didn't realize that this is only for list layouts, created with UICollectionViewCompositionalLayout.list.
But if I use a list layout, I don't think I have any opportunity to add multiple columns. Do I really have to choose between multiple columns and trailing swipe actions? Or is there some way to get both?
Hello,
I have the following subclass of UICompositionalCollectionViewLayout to get the stretchy header effect as shown below.
It works quite well, but I don't really have an experience with creating custom layouts so I thought I'd ask if maybe my implementation doesn't have some important flaws.
I once ran into persistent layout loop crash with this and I am not sure what exactly I changed but it stopped happening. However since I am using this layout on important screen, I would like to make sure there isn't obvious potential for the layout loop crash happening in App Store version.
I am particularly unsure about the shouldInvalidateLayout implementation. Originally I was returning true all the time, but decided to change it and only force invalidation for negative content offset which is when my header is supposed to stretch.
Here is the full code:
final class StretchyCompositionalLayout: UICollectionViewCompositionalLayout {
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var attrs = super.layoutAttributesForElements(in: rect) ?? []
guard let collectionView = collectionView else {
return attrs
}
let contentOffset = collectionView.contentOffset.y
guard contentOffset < 0 else {
return attrs
}
var newAttributes: UICollectionViewLayoutAttributes?
attrs.forEach({ attribute in
if attribute.indexPath.section == 0 && attribute.indexPath.item == 0 {
let startFrame = attribute.frame
newAttributes = attribute.copy() as? UICollectionViewLayoutAttributes
let newFrame: CGRect = .init(x: 0, y: contentOffset, width: startFrame.width, height: startFrame.height - contentOffset)
newAttributes?.frame = newFrame
}
})
if let new = newAttributes {
attrs.removeAll { attr in
return attr.indexPath.section == 0 && attr.indexPath.item == 0
}
attrs.insert(new, at: 0)
}
return attrs
}
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
guard let attributes = super.layoutAttributesForItem(at: indexPath) else {
return nil
}
let contentOffset = collectionView?.contentOffset.y ?? 1
guard contentOffset < 0 else {
return attributes
}
if indexPath.section == 0 && indexPath.item == 0 {
let attributes = attributes.copy() as? UICollectionViewLayoutAttributes ?? attributes
let startFrame = attributes.frame
let newFrame: CGRect = .init(x: 0, y: contentOffset, width: startFrame.width, height: startFrame.height - contentOffset)
attributes.frame = newFrame
return attributes
} else {
return super.layoutAttributesForItem(at: indexPath)
}
}
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
let contentOffset = collectionView?.contentOffset.y ?? 1
// There is visual glitch when 0 is used in this condition
if contentOffset < 1 {
return true
} else {
return super.shouldInvalidateLayout(forBoundsChange: newBounds)
}
}
}
Any feedback welcome!
Overview
I've found inconsistency on view lifecycle events between UIKit and SwiftUI as the following shows when using UIVPageViewController and UIHostingController as one of its pages.
SwiftUI View
onAppear is only called at the first time to display and never called in the other cases.
UIViewController
viewDidAppear is not called at the first time to display, but it's called when the page view controller changes its page displayed.
The whole view structure is as follows:
UIViewController (root)
UIPageViewController (as its container view)
UIHostingController (as its page)
SwiftUI View (as its content view)
UIViewControllerRepresentable (as a part of its body)
UIViewController (as its content)
Environment
Xcode Version 15.4 (15F31d)
iPhone 15 Pro (iOS 17.5) (Simulator)
iPhone 8 (iOS 15.0) (Simulator)
Sample code
import UIKit
import SwiftUI
class ViewController: UIViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {
private var pageViewController: UIPageViewController!
private var viewControllers: [UIViewController] = []
override func viewDidLoad() {
super.viewDidLoad()
setup()
}
private func setup() {
pageViewController.delegate = self
pageViewController.dataSource = self
let page1 = UIHostingController(rootView: MainPageView())
let page2 = UIViewController()
page2.view.backgroundColor = .systemBlue
let page3 = UIViewController()
page3.view.backgroundColor = .systemGreen
viewControllers = [page1, page2, page3]
pageViewController.setViewControllers([page1], direction: .forward, animated: false)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
guard let pageViewController = segue.destination as? UIPageViewController else { return }
self.pageViewController = pageViewController
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
print("debug: \(#function)")
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
print("debug: \(#function)")
guard let viewControllerIndex = viewControllers.firstIndex(of: viewController) else { return nil }
let previousIndex = viewControllerIndex - 1
guard previousIndex >= 0, viewControllers.count > previousIndex else { return nil }
return viewControllers[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
print("debug: \(#function)")
guard let viewControllerIndex = viewControllers.firstIndex(of: viewController) else { return nil }
let nextIndex = viewControllerIndex + 1
guard viewControllers.count != nextIndex, viewControllers.count > nextIndex else { return nil }
return viewControllers[nextIndex]
}
}
struct MainPageView: View {
var body: some View {
VStack(spacing: 0) {
PageContentView()
PageFooterView()
}
.onAppear { print("debug: \(type(of: Self.self)) onAppear") }
.onDisappear { print("debug: \(type(of: Self.self)) onDisappear") }
}
}
struct PageFooterView: View {
var body: some View {
Text("PageFooterView")
.padding()
.frame(maxWidth: .infinity)
.background(Color.blue)
.onAppear { print("debug: \(type(of: Self.self)) onAppear") }
.onDisappear { print("debug: \(type(of: Self.self)) onDisappear") }
}
}
struct PageContentView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> some UIViewController {
PageContentViewController()
}
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {}
}
class PageContentViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setup()
}
private func setup() {
view.backgroundColor = .systemYellow
let label = UILabel()
label.text = "PageContentViewController"
label.font = .preferredFont(forTextStyle: .title1)
view.addSubview(label)
label.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
label.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print("debug: \(type(of: Self.self)) \(#function)")
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
print("debug: \(type(of: Self.self)) \(#function)")
}
}
Logs
// Display the views
debug: MainPageView.Type onAppear
debug: PageFooterView.Type onAppear
// Swipe to the next page
debug: pageViewController(_:viewControllerAfter:)
debug: pageViewController(_:viewControllerBefore:)
debug: PageContentViewController.Type viewDidDisappear(_:)
debug: pageViewController(_:didFinishAnimating:previousViewControllers:transitionCompleted:)
debug: pageViewController(_:viewControllerAfter:)
// Swipe to the previous page
debug: PageContentViewController.Type viewDidAppear(_:)
debug: pageViewController(_:didFinishAnimating:previousViewControllers:transitionCompleted:)
debug: pageViewController(_:viewControllerBefore:)
As you can see here, onAppear is only called at the first time to display but never called in the other cases while viewDidAppear is the other way around.
Anyone else get these warnings when using UI Tab Bar in visionOS? Are these detrimental to pushing my visionOS app to the App Review Team?
import SwiftUI
import UIKit
struct HomeScreenWrapper: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> UITabBarController {
let tabBarController = UITabBarController()
// Home View Controller
let homeVC = UIHostingController(rootView: HomeScreen())
homeVC.tabBarItem = UITabBarItem(title: "Home", image: UIImage(systemName: "house"), tag: 0)
// Brands View Controller
let brandsVC = UIHostingController(rootView: BrandSelection())
brandsVC.tabBarItem = UITabBarItem(title: "Brands", image: UIImage(systemName: "bag"), tag: 1)
tabBarController.viewControllers = [homeVC, brandsVC]
return tabBarController
}
func updateUIViewController(_ uiViewController: UITabBarController, context: Context) {
// Update the UI if needed
}
}
struct HomeScreenWrapper_Previews: PreviewProvider {
static var previews: some View {
HomeScreenWrapper()
}
}
If I do something like this:
var viewControllers = navigationController.viewControllers
if let lastViewController = viewControllers.popLast() {
navigationController.viewControllers = viewControllers
navigationController.pushViewController(lastViewController, animated: false)
}
}
I got crash: pushing the same view controller instance more than once
If I set delay:
var viewControllers = navigationController.viewControllers
if let lastViewController = viewControllers.popLast() {
navigationController.viewControllers = viewControllers
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
navigationController.pushViewController(lastViewController, animated: false)
}
}
it will work but with unnecessary transitions.
Should it work like this in iOS 18 ?
iOS 18 22A5282m
navigationController.viewControllers = [UIViewController()]
or
navigationController.setViewControllers([UIViewController()], animated: false)
doesn't change navigation stack anymore.
We never received customer report this crash, and we could not see during development phase
However we can see this crash quite often on crash analytics.
I have gone through UIAlertController in code level, it always creates new one instead reusing it.
Please help me identify why this occurs?
Much appreciated
crash_session_2ecf1bdde30e402f9df795ea7681272b_DNE_0_v2_stacktrace.txt
After reading the documentation for TranslationSession and other API methods I got an impression that it will not be possible to use the Translation API with UI elements built with UIKit.
You don’t instantiate this class directly. Instead, you obtain an instance of it by adding a translationTask(_:action:) or translationTask(source:target:action:) function to the SwiftUI view containing the content you want to translate
So the main question I have to the engineers of mentioned framework is will there be any support for UIKit or app developers will have to rewrite their apps in SwiftUI just to be able to use the Translation API?
I’m seeing a crash in production for a small percentage of users, and have narrowed it down based on logging to happening as or very shortly after an alert is presented using SwiftUI.
This seems to be isolated to iOS 17.5.1, but since it’s a low-volume crash I can’t be sure there aren’t other affected versions. What can I understand from the crash report?
Here’s a simplified version of the code which presents the alert, which seems so simple I can’t understand why it would crash. And following that is the crash trace.
// View (simplified)
@MainActor public struct MyView: View {
@ObservedObject var model: MyViewModel
public init(model: MyViewModel) {
self.model = model
}
public var body: some View {
myViewContent
.overlay(clearAlert)
}
var clearAlert: some View {
EmptyView().alert(
"Are You Sure?",
isPresented: $model.isClearAlertVisible,
actions: {
Button("Keep", role: .cancel) { model.clearAlertKeepButtonWasPressed() }
Button("Delete", role: .destructive) { model.clearAlertDeleteButtonWasPressed() }
},
message: {
Text("This cannot be undone.")
}
)
}
}
// Model (simplified)
@MainActor public final class MyViewModel: ObservableObject {
@Published var isClearAlertVisible = false
func clearButtonWasPressed() {
isClearAlertVisible = true
}
func clearAlertKeepButtonWasPressed() {
// No-op.
}
func clearAlertDeleteButtonWasPressed() {
// Calls other code.
}
}
Incident Identifier: 36D05FF3-C64E-4327-8589-D8951C8BAFC4
Distributor ID: com.apple.AppStore
Hardware Model: iPhone13,2
Process: My App [379]
Path: /private/var/containers/Bundle/Application/B589E780-96B2-4A5F-8FCD-8B34F2024595/My App.app/My App
Identifier: com.me.MyApp
Version: 1.0 (1)
AppStoreTools: 15F31e
AppVariant: 1:iPhone13,2:15
Code Type: ARM-64 (Native)
Role: Foreground
Parent Process: launchd [1]
Coalition: com.me.MyApp [583]
Date/Time: 2024-06-21 20:09:20.9767 -0500
Launch Time: 2024-06-20 18:41:01.7542 -0500
OS Version: iPhone OS 17.5.1 (21F90)
Release Type: User
Baseband Version: 4.50.06
Report Version: 104
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x00000001a69998c0
Termination Reason: SIGNAL 5 Trace/BPT trap: 5
Terminating Process: exc handler [379]
Triggered by Thread: 0
Kernel Triage:
VM - (arg = 0x3) mach_vm_allocate_kernel failed within call to vm_map_enter
VM - (arg = 0x3) mach_vm_allocate_kernel failed within call to vm_map_enter
VM - (arg = 0x3) mach_vm_allocate_kernel failed within call to vm_map_enter
VM - (arg = 0x3) mach_vm_allocate_kernel failed within call to vm_map_enter
VM - (arg = 0x3) mach_vm_allocate_kernel failed within call to vm_map_enter
Thread 0 name:
Thread 0 Crashed:
0 libswiftCore.dylib 0x00000001a69998c0 _assertionFailure(_:_:file:line:flags:) + 264 (AssertCommon.swift:144)
1 AttributeGraph 0x00000001d0cd61a4 Attribute.init<A>(body:value:flags:update:) + 352 (Attribute.swift:473)
2 SwiftUI 0x00000001ac034054 closure #1 in Attribute.init<A>(_:) + 128 (<compiler-generated>:0)
3 SwiftUI 0x00000001ac033cac partial apply for closure #1 in Attribute.init<A>(_:) + 32 (<compiler-generated>:0)
4 libswiftCore.dylib 0x00000001a6ad0450 withUnsafePointer<A, B>(to:_:) + 28 (LifetimeManager.swift:128)
5 SwiftUI 0x00000001ad624d14 closure #2 in UIKitDialogBridge.startTrackingUpdates(actions:) + 268 (UIKitDialogBridge.swift:370)
6 SwiftUI 0x00000001ad624ae0 UIKitDialogBridge.startTrackingUpdates(actions:) + 248 (UIKitDialogBridge.swift:369)
7 SwiftUI 0x00000001ad6250cc closure #4 in UIKitDialogBridge.showNewAlert(_:id:) + 72 (UIKitDialogBridge.swift:471)
8 SwiftUI 0x00000001abfdd050 thunk for @escaping @callee_guaranteed () -> () + 36 (:-1)
9 UIKitCore 0x00000001aa5722e4 -[UIPresentationController transitionDidFinish:] + 1096 (UIPresentationController.m:651)
10 UIKitCore 0x00000001aa571d88 __56-[UIPresentationController runTransitionForCurrentState]_block_invoke.114 + 320 (UIPresentationController.m:1390)
11 UIKitCore 0x00000001aa5cb9ac -[_UIViewControllerTransitionContext completeTransition:] + 116 (UIViewControllerTransitioning.m:304)
12 UIKitCore 0x00000001aa34a91c __UIVIEW_IS_EXECUTING_ANIMATION_COMPLETION_BLOCK__ + 36 (UIView.m:16396)
13 UIKitCore 0x00000001aa34a800 -[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:] + 624 (UIView.m:16429)
14 UIKitCore 0x00000001aa349518 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 436 (UIView.m:0)
15 UIKitCore 0x00000001aa356b14 -[UIViewAnimationState animationDidStop:finished:] + 192 (UIView.m:2400)
16 UIKitCore 0x00000001aa356b84 -[UIViewAnimationState animationDidStop:finished:] + 304 (UIView.m:2422)
17 QuartzCore 0x00000001a96f8c50 run_animation_callbacks(void*) + 132 (CALayer.mm:7714)
18 libdispatch.dylib 0x00000001aff61dd4 _dispatch_client_callout + 20 (object.m:576)
19 libdispatch.dylib 0x00000001aff705a4 _dispatch_main_queue_drain + 988 (queue.c:7898)
20 libdispatch.dylib 0x00000001aff701b8 _dispatch_main_queue_callback_4CF + 44 (queue.c:8058)
21 CoreFoundation 0x00000001a808f710 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16 (CFRunLoop.c:1780)
22 CoreFoundation 0x00000001a808c914 __CFRunLoopRun + 1996 (CFRunLoop.c:3149)
23 CoreFoundation 0x00000001a808bcd8 CFRunLoopRunSpecific + 608 (CFRunLoop.c:3420)
24 GraphicsServices 0x00000001ecf3c1a8 GSEventRunModal + 164 (GSEvent.c:2196)
25 UIKitCore 0x00000001aa6c490c -[UIApplication _run] + 888 (UIApplication.m:3713)
26 UIKitCore 0x00000001aa7789d0 UIApplicationMain + 340 (UIApplication.m:5303)
27 SwiftUI 0x00000001ac27c148 closure #1 in KitRendererCommon(_:) + 168 (UIKitApp.swift:51)
28 SwiftUI 0x00000001ac228714 runApp<A>(_:) + 152 (UIKitApp.swift:14)
29 SwiftUI 0x00000001ac2344d0 static App.main() + 132 (App.swift:114)
30 My App 0x00000001001e7bfc static MyApp.$main() + 52 (MyApp.swift:0)
31 My App 0x00000001001e7bfc main + 64
32 dyld 0x00000001cb73de4c start + 2240 (dyldMain.cpp:1298)
Hey everyone,
I’m facing a bug when using UIVisualEffectView in a SwiftUI context via UIViewRepresentable. When the SwiftUI view modifier .blur(radius: xx, opaque: true) is applied to it during rotation, the blur effect isn’t applied. Instead, the view becomes completely white or black, depending on the UIBlurEffect.Style applied to the UIVisualEffectView.
I’m not sure how to proceed with this issue and am seeking your help. Below is a simple, reproducible piece of code:
import SwiftUI
struct ContentView: View {
var body: some View {
ZStack {
Circle()
.fill(.pink)
GlassBackgroundView()
.blur(radius: 7, opaque: true)
}
.ignoresSafeArea()
}
}
#Preview {
ContentView()
}
private struct GlassBackgroundView: UIViewRepresentable {
func makeUIView(context: Context) -> UIVisualEffectView {
UIVisualEffectView(effect: UIBlurEffect(style: .regular))
}
func updateUIView(_ uiView: UIVisualEffectView, context: Context) { }
}
We have a UITabBarController in our iPhone App which has 5 tabs with UITableViewControllers (constructed from the storyboard). Before iOS18 beta 1 (and 2) this was working fine without any problems (objective-C).
Since iOS18 beta 1 (and beta 2 still has this problem) a strange render glitch occurs when activating a tab from the tab bar at the bottom.
As soon as a tab is activated (by tapping on the icon at the bottom) the tab with the UITableViewController becomes visible and draws its content starting at the very top of the screen (pos 0,0) right through/over the Navigation bar which at that point is showing a title and a rightBarButtonItem.
The tab with the UITableViewController seems not aware there is a navigation bar visible.
Then after ~0.3 seconds the tab with the UITableViewContoller is automatically rendered again or moved down and now its content starts below the UINavigationBar as expected, this is 100% reproducible and occurs on every activation of a tab in the UITabBarController.
Is anyone else also getting this behavior in their App since iOS18?
I'm aware that UITabBarController is being renewed but I can't find any information on why this behavior might occur. I was hoping beta 2 would solve the problem but it doesn't.
Constructing the UITabBarController in the code with the new UITab objects (instead of constructing them from the storyboard) also shows this problem.
I have created an app for iOS using React Native. I've gotten the app to a point where it works on the iPhone simulator via the Expo App. It even works when creating a build of the app to distribute using TestFlight. Now, I want to add Google Ads into the app. However, I've learned that Google Ads won't work via an Expo build. Instead one has to create a development build to test the ads in the app and see how they look.
I've also finally been able to compile a successful development build using eas (expo application services). When I install the app on the simulator and try to open it however, the app crashes almost immediately and I don't know why. I have tried deciphering the symbolicated crash report, but I have not been able to figure out what could be causing the error. It looks like it has something to do with the user interface.
Below is the thread where the app crashes:
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x11324a14a __pthread_kill + 10
1 libsystem_pthread.dylib 0x1132abebd pthread_kill + 262
2 libsystem_c.dylib 0x7ff80016dd1c abort + 133
3 libc++abi.dylib 0x7ff8002c6d12 abort_message + 241
4 libc++abi.dylib 0x7ff8002b951a demangling_terminate_handler() + 266
5 libobjc.A.dylib 0x7ff800061fba _objc_terminate() + 96
6 libc++abi.dylib 0x7ff8002c616b std::__terminate(void (*)()) + 6
7 libc++abi.dylib 0x7ff8002c6126 std::terminate() + 54
8 libdispatch.dylib 0x7ff8001796ec _dispatch_client_callout + 28
9 libdispatch.dylib 0x7ff80017d1e2 _dispatch_block_invoke_direct + 508
10 FrontBoardServices 0x7ff807a8b3a7 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 30
11 FrontBoardServices 0x7ff807a8b281 -[FBSMainRunLoopSerialQueue _targetQueue_performNextIfPossible] + 188
12 FrontBoardServices 0x7ff807a8b3cf -[FBSMainRunLoopSerialQueue _performNextFromRunLoopSource] + 19
13 CoreFoundation 0x7ff800429ff3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
14 CoreFoundation 0x7ff800429f35 __CFRunLoopDoSource0 + 157
15 CoreFoundation 0x7ff800429732 __CFRunLoopDoSources0 + 215
16 CoreFoundation 0x7ff800423e67 __CFRunLoopRun + 919
17 CoreFoundation 0x7ff8004236ed CFRunLoopRunSpecific + 557
18 GraphicsServices 0x7ff8103ba08f GSEventRunModal + 137
19 UIKitCore 0x7ff805cdf6ee -[UIApplication _run] + 972
20 UIKitCore 0x7ff805ce416e UIApplicationMain + 123
21 LeftOff 0x10f870380 main + 96
22 dyld_sim 0x112d3a3e0 start_sim + 10
23 dyld 0x113d57366 start + 1942
I have been trying to solve this for some days now and could really use some help. I have tried changing versions of dependencies in my app too, with a focus on those that manage the UI. For example, I have changed packages such as react-native-ranimated, react-navigation/stack, react-native-gesture-handler, and react-native-screens to name a few. Nothing has worked so far. Please help.
In the past, it seemed that if you used the app switcher and killed the app, that state restoration data would not persist, and starting the app again would not load any stored state data. But now (at lest in iOS 17) that is no longer the case.
There are situations where the old state might cause issues, which we obviously need to fix, but users should be able to clear the state data.
I am not using sessions and am using the older methods - application:shouldSaveApplicationState: and application:shouldRestoreApplicationState:.
My question is, how can I tell my users to reset/clear state restoration data if needed?