I am currently implementing multiple scenes in my React Native / Swift application (one scene for the phone and one scene for CarPlay). I am facing an issue where one scene renders completely white (on the iPhone) but I can see in the console that the code is running (for example if I add a console.log to the App.tsx I can see that console log happen in XCode).
There are no errors when building the app in XCode, and testing with the simulator CarPlay appears to render the correct output, but there is no component being rendered on the simulated phone screen (just white).
AppDelegate.swift
import CarPlay
import React
import React_RCTAppDelegate
import ReactAppDependencyProvider
import UIKit
@main
class AppDelegate: RCTAppDelegate {
var rootView: UIView?;
static var shared: AppDelegate { return UIApplication.shared.delegate as! AppDelegate }
override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
self.moduleName = "appName"
self.dependencyProvider = RCTAppDependencyProvider()
self.initialProps = [:]
self.rootView = self.createRootView(
with: RCTBridge(
delegate: self,
launchOptions: launchOptions
),
moduleName: self.moduleName!,
initProps: self.initialProps!
);
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
override func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
if (connectingSceneSession.role == UISceneSession.Role.carTemplateApplication) {
let scene = UISceneConfiguration(name: "CarPlay", sessionRole: connectingSceneSession.role)
scene.delegateClass = CarSceneDelegate.self
return scene
}
let scene = UISceneConfiguration(name: "Phone", sessionRole: connectingSceneSession.role)
scene.delegateClass = PhoneSceneDelegate.self
return scene
}
override func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {}
override func sourceURL(for bridge: RCTBridge) -> URL? {
self.bundleURL()
}
override func bundleURL() -> URL? {
#if DEBUG
RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
#else
Bundle.main.url(forResource: "main", withExtension: "jsbundle")
#endif
}
}
PhoneSceneDelegate.swift
import Foundation
import UIKit
import SwiftUI
class PhoneSceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?;
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if session.role != .windowApplication {
return
}
guard let appDelegate = (UIApplication.shared.delegate as? AppDelegate) else {
return
}
guard let windowScene = (scene as? UIWindowScene) else {
return
}
let rootViewController = UIViewController()
rootViewController.view = appDelegate.rootView;
let window = UIWindow(windowScene: windowScene)
window.rootViewController = rootViewController
self.window = window
window.makeKeyAndVisible()
}
}
App.tsx
import React, {useEffect, useState} from 'react';
import type {PropsWithChildren} from 'react';
import {CarPlay, ListTemplate} from 'react-native-carplay';
import {
ScrollView,
StatusBar,
StyleSheet,
Text,
useColorScheme,
View,
} from 'react-native';
import {
Colors,
DebugInstructions,
Header,
LearnMoreLinks,
ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
type SectionProps = PropsWithChildren<{
title: string;
}>;
function Section({children, title}: SectionProps): React.JSX.Element {
const isDarkMode = useColorScheme() === 'dark';
return (
<View style={styles.sectionContainer}>
<Text
style={[
styles.sectionTitle,
{
color: isDarkMode ? Colors.white : Colors.black,
},
]}>
{title}
</Text>
<Text
style={[
styles.sectionDescription,
{
color: isDarkMode ? Colors.light : Colors.dark,
},
]}>
{children}
</Text>
</View>
);
}
function App(): any { // React.JSX.Element
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
const [carPlayConnected, setCarPlayConnected] = useState(CarPlay.connected);
useEffect(() => {
function onConnect() {
setCarPlayConnected(true);
CarPlay.setRootTemplate(new ListTemplate(/** This renders fine on the CarPlay side */));
}
function onDisconnect() {
setCarPlayConnected(false);
}
CarPlay.registerOnConnect(onConnect);
CarPlay.registerOnDisconnect(onDisconnect);
return () => {
CarPlay.unregisterOnConnect(onConnect);
CarPlay.unregisterOnDisconnect(onDisconnect);
};
});
if (carPlayConnected) {
console.log('car play connected');
} else {
console.log('car play not connected');
}
const safePadding = '5%';
// This doesn't render on the phone?
return (
<View style={backgroundStyle}>
<StatusBar
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
backgroundColor={backgroundStyle.backgroundColor}
/>
<ScrollView
style={backgroundStyle}>
<View style={{paddingRight: safePadding}}>
<Header/>
</View>
<View
style={{
backgroundColor: isDarkMode ? Colors.black : Colors.white,
paddingHorizontal: safePadding,
paddingBottom: safePadding,
}}>
<Section title="Step One">
Edit <Text style={styles.highlight}>App.tsx</Text> to change this
screen and then come back to see your edits.
</Section>
<Section title="See Your Changes">
<ReloadInstructions />
</Section>
<Section title="Debug">
<DebugInstructions />
</Section>
<Section title="Learn More">
Read the docs to discover what to do next:
</Section>
<LearnMoreLinks />
</View>
</ScrollView>
</View>
);
}
const styles = StyleSheet.create({
sectionContainer: {
marginTop: 32,
paddingHorizontal: 24,
},
sectionTitle: {
fontSize: 24,
fontWeight: '600',
},
sectionDescription: {
marginTop: 8,
fontSize: 18,
fontWeight: '400',
},
highlight: {
fontWeight: '700',
},
});
export default App;
I have been attempting to get this working now for some 20+ hours with no luck with searching for answers elsewhere. I am very new to building apps with React Native and Swift so could do with some support.
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.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
We have been having problems with our app clip not working when sharing through iMessage. The app and app clip are published and work correctly when scanning a QR code that points to the URL: https://www.coderus.com/locations?loc=1 however if this same URL is shared through the iMessage app, a link to the website displays and not the app clip card.
We have confirmed that:
AASA file is available and has the type application/json
Both devices are above iOS 14
Both devices are in each other's contacts
The website has the meta tag for the smart app clip banner
The website has a meta tag for the og:image
Launch experiences have been configured on AppStoreConnect - as said before, the QR codes work correctly
The link leads to a 404 page, I wasn't sure if there needs to be an actual page that the link points to as app clips seem to work fine without when scanning the QR code through the camera app.
Hi, when I run NavigationSplitView as shown below, the sidebar opens and closes smoothly.
struct TestingView: View {
var body: some View {
NavigationSplitView {
Text("Sidebar")
} detail: {
Text("Detail")
}
}
}
However, when I add a minimum width, the sidebar animation starts to lag. I tried various wapping solutions, but I couldn’t get rid of the stutter.
struct TestingView: View {
var body: some View {
NavigationSplitView {
Text("Sidebar")
} detail: {
Text("Detail")
}
.frame(minWidth: 800)
}
}
As a solution, I had to disable the animation completely:
.animation(nil, value: columnVisibility)
Is there a way to keep the animation without the stuttering?
Adding environment value openURL or dismiss to a View in a NavigationStack, without even using it, causes an infinite refresh loop.
What doesn't work:
a)
struct ViewA: View {
@State private var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
ViewB()
}
}
}
struct ViewB: View {
@Environment(\.openURL) var openURL
var body: some View {
NavigationLink("Next", value: 1)
.navigationDestination(for: Int.self, destination: itemView)
}
func itemView(_ item: Int) -> some View {
Text("Item \(item)")
}
}
Prints ViewB: _openURL changed. infinitely.
b) Passing the path to ViewB and appending the value with a Button
What works:
a)
.navigationDestination(for: Int.self) {
Text("Item \($0)")
}
Prints
ViewB: @self, @identity, _openURL changed.
ViewB: @self, _openURL changed.
ViewB: _openURL changed. (3 times)
b) Handling the destination on ViewA, which is not ideal for my use case.
Prints
ViewB: @self, @identity, _openURL changed.
ViewB: _openURL changed. (5 times)
While the workaround would work, it is still unclear how the environment value can cause the freeze (and eventual crash). Also that passing a function as parameter fails, while providing the destination in place does not. The code is stripped down to the minimal reproducible version. Any thoughts?
Hello,
I am encountering an issue with .refreshable(action:) in ScrollView.
The refresh action works as expected when performing a pull-to-refresh. However, if I put the app in the background while the refresh operation is in progress, the refresh indicator remains visible on the screen when I return to the foreground and does not disappear.
Once I interact with the ScrollView after returning to the foreground, the refresh indicator disappears, and the functionality itself is not affected.
I initially attempted to resolve this issue by triggering a view redraw when scenePhase changes. However, since my app presents the SwiftUI view using UIHostingController, the scenePhase from the environment does not seem to function correctly.
This issue occurs on iOS 17.1 but does not appear on iOS 16.1.1.
Is there a known way to resolve this unexpected behavior?
Below is a simplified sample code (some parts are omitted):
struct MyView: View {
@StateObject private var model: MyModel
var body: some View {
ScrollView {
// My ContentViews...
}
.refreshable {
do {
try await self.model.refresh()
} catch {
// Handle error
}
}
}
}
@MainActor
final class MyModel: ObservableObject {
// === Some Code ===
func refresh() async throws {
let data = try await self.fetchData()
self.data = Array(OrderedSet(data))
}
}
I apologize for any mistakes in my English, as I am using a translation tool.
Thank you in advance for your help!
Best regards,
The DeviceActivityReport view does not render immediately when added to the view hierarchy. Instead, it requires repeated navigation to the screen hosting the DeviceActivityReport view for it to appear.
Furthermore, there is no programmatic way to determine whether the view is being rendered for the user, leading to an inconsistent and often poor user experience.
I've created a sample project that demonstrates the issue.
Hello Apple Developer Community,
I’m experiencing an issue with my iOS app, "WaterReminder," where it builds successfully in Xcode 16.2 but crashes immediately upon launch in the iPhone 16 Pro Simulator running iOS 18.3.1. The crash is accompanied by a "Thread 1: signal SIGABRT" error, and the Xcode console logs indicate a dyld error related to XCTest.framework/XCTest not being loaded. I’ve tried several troubleshooting steps, but the issue persists, and I’d appreciate any guidance or insights from the community.
Here are the details:
Environment:
Xcode Version: 16.2
Simulator: iPhone 16 Pro, iOS 18.3.1
App: WaterReminder (written in SwiftUI 6)
Build Configuration: Debug
Issue Description:
The app builds without errors, but when I run it in the iPhone 16 Pro Simulator, it shows a white screen and crashes with a SIGABRT signal. The Xcode debugger highlights the issue in the main function or app delegate, and the console logs show the following error:
dyld[7358]: Library not loaded: @rpath/XCTest.framework/XCTest
Referenced from: <549B4D71-6B6A-314B-86BE-95035926310E> /Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/WaterReminder.debug.dylib
Reason: tried: '/Users/faytek/Library/Developer/Xcode/DerivedData/WaterReminder-cahqrulxghamvyclxaozotzrbsiz/Build/Products/Debug-iphonesimulator/XCTest.framework/XCTest' (no such file), '/Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/Frameworks/XCTest.framework/XCTest' (no such file), '/Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/XCTest.framework/XCTest' (no such file), '/Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/Frameworks/XCTest.framework/XCTest' (no such file), '/Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/XCTest.framework/XCTest' (no such file), '/Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/Frameworks/XCTest.framework/XCTest' (no such file), '/Library/Developer/CoreSimulator/Volumes/iOS_22D8075/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.3.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/XCTest.framework/XCTest' (no such file)
What I’ve Tried:
◦ Verified that FBSnapshotTestCase is correctly added to the "Embed Frameworks" build phase.
◦ Confirmed that the Framework Search Paths in build settings point to the correct location.
◦ Ensured that all required frameworks are available in the dependencies folder.
◦ Cleaned the build folder (Shift + Option + Command + K) and rebuilt the project.
◦ Checked the target configuration to ensure XCTest.framework isn’t incorrectly linked to the main app target (it’s only in test targets).
◦ Updated Xcode and the iOS Simulator to the latest versions.
◦ Reset the simulator content and settings.
Despite these steps, the app continues to crash with the same dyld error and SIGABRT signal. I suspect there might be an issue with how XCTest.framework is being referenced or loaded in the simulator, possibly related to using SwiftUI 6, but I’m unsure how to resolve it.
Could anyone provide advice on why XCTest.framework is being referenced in my main app (since it’s not intentionally linked there) or suggest additional troubleshooting steps? I’d also appreciate any known issues or workarounds specific to Xcode 16.2, iOS 18.3.1, and SwiftUI 6.
Thank you in advance for your help!
Best regards,
Faycel
Prime Objective
I am trying to have a scroll view with a fixed header, a fixed footer, and a WKWebView in between. Using JavaScript, the height of the webView is determined and set to be large enough to hold the entire content.
The Problem
When selecting text on the webView, the view does not scroll when the edges are reached (this works if the webView is shown without being embedded in a Scroll view, or if it is the last element)
What did I try?
I tried reading the scroll view, or adding a gesture recognizer, but all of that does not work because the selection is essentially a system task
Sourcecode
Sourcecode to demonstrate the issue can be found on GitHub
In an AppKit document-based project created by Xcode, setting canConcurrentlyReadDocuments to true allows new documents to open normally in Swift 5, but switching to Swift 6 causes an error.
Judging from the error message, it seems to be a threading issue, but I’m not sure how to adjust the code to support the Swift 6 environment.
The project is the most basic code from an Xcode-created document-based project without any modifications, except for changing the Swift version to 6 and setting canConcurrentlyReadDocuments to true.
Source code: https://drive.google.com/file/d/1ryb2TaU6IX884q0h5joJqqZwSX95Q335/view?usp=sharing
AppDelegate.swift
import Cocoa
@main
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification)
{
// Insert code here to initialize your application
}
func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
}
func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
return true
}
}
Document.swift
import Cocoa
class Document: NSDocument {
override init() {
super.init()
// Add your subclass-specific initialization here.
}
override class var autosavesInPlace: Bool {
return true
}
override class func canConcurrentlyReadDocuments(ofType typeName: String) -> Bool {
true
}
override func canAsynchronouslyWrite(to url: URL, ofType typeName: String, for saveOperation: NSDocument.SaveOperationType) -> Bool {
true
}
override func makeWindowControllers() {
// Returns the Storyboard that contains your Document window.
let storyboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: nil)
let windowController = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("Document Window Controller")) as! NSWindowController
self.addWindowController(windowController)
}
override func data(ofType typeName: String) throws -> Data {
// Insert code here to write your document to data of the specified type, throwing an error in case of failure.
// Alternatively, you could remove this method and override fileWrapper(ofType:), write(to:ofType:), or write(to:ofType:for:originalContentsURL:) instead.
// throw NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: nil)
return Data()
}
override func read(from data: Data, ofType typeName: String) throws {
// Insert code here to read your document from the given data of the specified type, throwing an error in case of failure.
// Alternatively, you could remove this method and override read(from:ofType:) instead.
// If you do, you should also override isEntireFileLoaded to return false if the contents are lazily loaded.
// throw NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: nil)
}
}
ViewController.swift
import Cocoa
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
https://developer.apple.com/documentation/mapkit/mkgeojsondecoder?changes=__9&language=objc
I am trying to use this decoder to obtain single points form a geojson file. I am able to do this successfully however, when using MapKit for iOS 17+ I am unable to use a ForEach to iterate through these points (stored in an array) and display these on the map as a custom annotation or even a marker.
MapAnnotation(coordinate: point.coordinate) {
VStack {
Image(systemName: "mappin.circle.fill")
.resizable()
.frame(width: 25, height: 25)
.foregroundColor(.purple)
if let title = point.title {
Text(title)
.font(.caption)
.foregroundColor(.purple)
.padding(2)
.background(Color.white.opacity(0.8))
.cornerRadius(3)
}
}
}
When call:
[UITabBarController setViewControllers:animated:]
It crashed and raise an Fatal Exception:
Fatal Exception: NSInternalInconsistencyException Attempting to select a view controller that isn't a child! (null)
the crash stack is:
Fatal Exception: NSInternalInconsistencyException
0 CoreFoundation 0x8408c __exceptionPreprocess
1 libobjc.A.dylib 0x172e4 objc_exception_throw
2 Foundation 0x82215c _userInfoForFileAndLine
3 UIKitCore 0x38a468 -[UITabBarController transitionFromViewController:toViewController:transition:shouldSetSelected:]
4 UIKitCore 0x3fa8a4 -[UITabBarController _setSelectedViewController:performUpdates:]
5 UIKitCore 0x3fa710 -[UITabBarController setSelectedIndex:]
6 UIKitCore 0x8a5fc +[UIView(Animation) performWithoutAnimation:]
7 UIKitCore 0x3e54e0 -[UITabBarController _setViewControllers:animated:]
8 UIKitCore 0x45d7a0 -[UITabBarController setViewControllers:animated:]
And it appear sometimes, what's the root cause?
In the good old days, it was possible to retrieve dynamically the UnknownFSObjectIcon.icns icon using:
[[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kUnknownFSObjectIcon)];
Now, this solution is considered to be deprecated (but is still working) by recent macOS SDKs.
[Q] What is the modern equivalent of this solution?
Notes:
Yes, reading the file directly works but is more fragile than using a System API.
Yes, Xcode suggests to use the iconForContentType: method but I haven't found which UTType should be used.
Hello! We can animate Text color via foregroundStyle very nicely in SwiftUI like so:
Text("Some text here")
.foregroundStyle(boolValue ? Color.green : Color.blue)
withAnimation {
boolValue.toggle()
}
However, if the foregroundStyle is a gradient, the color of the Text view changes immediately without animation.
The code below works to animate a gradient foregroundStyle on an SF Symbol, but it does not work when applied to a Text view. Is it possible to animate a Text view foregroundStyle between gradient values?
Image(systemName: "pencil.circle.fill")
.foregroundStyle(boolValue ? .linearGradient(colors: [.red, .orange], startPoint: .top, endPoint: .bottom) : .linearGradient(colors: [.green, .blue], startPoint: .top, endPoint: .bottom))
Thanks for your help!
Hello,
we are presenting a UIDocumentInteractionController within our app, so the user can share some documents. Sharing basically works but we are facing the problem that the two delegate methods
documentInteractionController(UIDocumentInteractionController, willBeginSendingToApplication: String?)
and
documentInteractionController(UIDocumentInteractionController, didEndSendingToApplication: String?)
are never being called. Other delegate methods such as
documentInteractionControllerWillBeginPreview(UIDocumentInteractionController)
are called just fine. Everything worked as expected when we last checked a year ago or so, but doesn't anymore now, even after updating to the latest iOS 18.3.
Does anybody know of a solution for this?
For reference, this is the simplified code we are using the reproduce the issue:
import UIKit
import OSLog
class ViewController: UIViewController, UIDocumentInteractionControllerDelegate {
let log = Logger(subsystem: "com.me.pdfshare", category: "app")
var documentInteractionController: UIDocumentInteractionController!
override func viewDidLoad() {
super.viewDidLoad()
guard let pdfURL = Bundle.main.url(forResource: "test", withExtension: "pdf") else {
return
}
documentInteractionController = UIDocumentInteractionController(url: pdfURL)
documentInteractionController.delegate = self
documentInteractionController.presentPreview(animated: true)
}
// MARK: - UIDocumentInteractionControllerDelegate
func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
log.notice("documentInteractionControllerViewControllerForPreview")
return self
} // This will be called.
func documentInteractionController(_ controller: UIDocumentInteractionController, willBeginSendingToApplication application: String?) {
log.notice("willBeginSendingToApplication")
} // This will NOT be called.
func documentInteractionController(_ controller: UIDocumentInteractionController, didEndSendingToApplication application: String?) {
log.notice("didEndSendingToApplication")
} // This will NOT be called.
}
I have a share extension in my app, that shall allow users to send CSV files, custom app files, and selected text to my app via the share sheet for importing that data.
So, the share extension should activate when the user has selected either:
CSV or plain text files
Custom UTI app files
Text selected in other apps
The supported file types have been defined in as a predicate query according to the example in the docs
This works all fine on iOS, and the file sharing also works on the Mac.
However, on macOS, my app is not shown as a target in the share sheet when the user selects text in other apps and tries to share that text via the context menu.
Does macOS need a different configuration to enable a share extension for selected text?
This is how my Info.plist of the Mac share extension looks like:
...
<plist version="1.0">
<dict>
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>NSExtensionActivationRule</key>
<string>SUBQUERY (
extensionItems,
$extensionItem,
SUBQUERY (
$extensionItem.attachments,
$attachment,
ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.plain-text" ||
ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.myCompany.myApp.customFormat" ||
ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.delimited-values-text"
).@count == $extensionItem.attachments.@count
).@count >= 1</string>
</dict>
...
</dict>
</plist>
I know there is a NSExtensionActivationSupportsText but it seems this cannot be combined with a subquery rule.
Is there a way to explicitly enable text activation within the subquery rule?
I have created an AppIntent and added it to shortcuts to be able to read by Siri. When I say the phrase, the Siri intent dialog appears just fine. I have added a custom SwiftUI View inside Siri dialog box with 2 buttons with intents. The callback or handling of those buttons is not working when initiated via Siri. It works fine when I initiate it in shortcuts. I tried using the UIButton without the intent action as well but it did not work. Here is the code.
static let title: LocalizedStringResource = "My Custom Intent"
static var openAppWhenRun: Bool = false
@MainActor
func perform() async throws -> some ShowsSnippetView & ProvidesDialog {
return .result(dialog: "Here are the details of your order"), content: {
OrderDetailsView()
}
}
struct OrderDetailsView {
var body: some View {
HStack {
if #available(iOS 17.0, *) {
Button(intent: ModifyOrderIntent(), label : {
Text("Modify Order")
})
Button(intent: CancelOrderIntent(), label : {
Text("Cancel Order")
})
}
}
}
}
struct ModifyOrderIntent: AppIntent {
static let title: LocalizedStringResource = "Modify Order"
static var openAppWhenRun: Bool = true
@MainActor
func perform() async throws -> some OpensIntent {
// performs the deeplinking to app to a certain page to modify the order
}
}
struct CancelOrderIntent: AppIntent {
static let title: LocalizedStringResource = "Cancel Order"
static var openAppWhenRun: Bool = true
@MainActor
func perform() async throws -> some OpensIntent {
// performs the deeplinking to app to a certain page to cancel the order
}
}
Button(action: {
if let url = URL(string: "myap://open-order") {
UIApplication.shared.open(url)
}
}
I have a struct that holds an instance of UINavigationController:
struct NavigationController {
static let shared = UINavigationController()
}
I use NavigationController.shared to push and pop ViewControllers around the app, rather than using the ViewController's .navigationController property.
The issue I'm having is that when I pop I get new instances of my previous ViewController, this is my hierarchy:
(0) UIWindow
|
---- (1) NavigationController (is set as the UIWindow.rootViewController)
|
---- (2) UITabBarController (is set with NavigationController.shared.setViewControllers)
|
---- (3) ViewController (HomeVC) (is the first tab of the UITabController)
|
---- (4) ViewController (ScanVC) (is pushed into the stack by NavigationController.shared.pushViewController)
---- (5) ViewController (NotificationsVC)
---- (6) ViewController (SettingsVC)
I put a print statement in my HomeVC in the viewDidLoad method
My understanding is that the viewDidLoad should only be called once in the lifecycle of a ViewController
When I go back to the HomeVC from the ScanVC then the print always gets triggered which means I have a new instance of the HomeVC
This is the print statement I created inside the viewDidLoad method:
print("\(#function) View Did Load, instance: \(self)")
Here's the output from going back and forth from the HomeVC to ScanVC:
viewDidLoad() View Did Load, instance: <HomeVC: 0x118db0000>
viewDidLoad() View Did Load, instance: <HomeVC: 0x118db3100>
viewDidLoad() View Did Load, instance: <HomeVC: 0x118db0700>
Any one has any suggestions on how to fix this? Because ideally going back to the HomeVC should not instantiate a new ViewController.
I tested this on a small test project and viewDidLoad would only be triggered once when the ViewController was instantiated.
Platform Specs:
Xcode 16.2
Swift 6.0.3
iOS 18.2 + iOS Simulator 18.3.1
Issue:
Refer to the following code:
struct CustomView: View {
@Binding var prop: CustomStruct
init(prop p: Binding<CustomStruct>) {
_prop = p
}
init(isPreview: Bool) {
let p = CustomStruct()
_prop = .constant(p)
}
var body: some View {
VStack {
Text("hi")
}
}
}
#Preview {
CustomView(isPreview: true)
.preferredColorScheme(.dark)
}
The first constructor is for normal app functionality (and previews/functions correctly when used with the rest of the app in the ContentView preview tab). The second constructor is for previewing only CustomView in its own preview tab. This constructor does not work when previewing in the same file, as shown above. It triggers an ambiguous crash, stating that the diagnostic log (which obviously provides no clear information) should be checked.
I have isolated the issue to be in the Binding reassignment in the second constructor. Replacing CustomStruct with anything but another struct, like an enum or primitive, fixes the issue.
Note: This bug only occurs when previewing (either through the #Preview macro or PreviewProvider struct).
Hello. Recently, our app has been experiencing crashes with the message 'Attempting to attach window to an invalidated scene' when creating a UIWindow.
Our code stores the UIWindowScene provided in the scene(:willConnectTo:options:) function in a global variable and does not change the set scene until the scene(:willConnectTo:options:) function is called again. Additionally, we do not perform any actions related to the disconnect event.
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
hudManager.setup(windowScene: windowScene)
// ...
}
func sceneDidDisconnect(_ scene: UIScene) {
// do nothing
}
In all crash logs, the activationState of the WindowScene is "unattached", so I initially thought that creating a UIWindow with a scene in the 'unattached' state should be avoided.
However, in the scene(_:willConnectTo:options:) function, the scene's state is also 'unattached', yet the UIWindow is created successfully here, which makes me think that deciding whether to create a window based on the activationState is incorrect.
I did find that trying to create a UIWindow with a scene after it has been disconnected causes a crash.
func sceneDidDisconnect(_ scene: UIScene) {
// Crash occur here and scene's state is `unattached`
let window = UIWindow(windowScene: scene as! UIWindowScene)
}
If the activationState alone cannot be used to determine the validity of a scene, is there another way to check the validity of a Scene? Thank you
I have an application named "XY" that has been launched in several countries. Now, I intend to launch it in Turkey, but we are facing legal issues preventing us from using "XY" as the app's display name. Following the documentation, I localized the app's display name to "ZX" for both Turkish and English (Turkey). However, when users change their device settings, they do not see an option for English (Turkey) language selection. I assumed that for Turkish users, English (Turkey) would be the default language, but this is not the case. Could someone please assist me in resolving this issue? I've investigated options for localizing the display name based on region, but it seems that this functionality isn't feasible on iOS. In contrast, it's relatively straightforward to achieve on Android platforms.