Unable to record and play the new contacts permission system dialog.
App: https://developer.apple.com/documentation/contacts/accessing-a-person-s-contact-data-using-contacts-and-contactsui
func handleContactsAccessAlert() {
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
let allowButton = springboard.buttons["Allow Full Access"]
allowButton.tap()
let access6ContactsButton = springboard.alerts["Allow full access to 6 contacts?"].scrollViews.otherElements.buttons["Allow"]
access6ContactsButton.tap()
}
func handleContactsPermissionAlert() {
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
let allowButton = springboard.buttons["Continue"]
if allowButton.exists {
allowButton.tap()
sleep(5)
handleContactsAccessAlert()
}
}
func testContactPermissions() {
let app = XCUIApplication()
app.launch()
app.buttons["Request Access"].tap()
sleep(5)
handleContactsPermissionAlert()
sleep(5)
app.collectionViews/*@START_MENU_TOKEN@*/.staticTexts["Kate Bell"]/*[[".cells.staticTexts[\"Kate Bell\"]",".staticTexts[\"Kate Bell\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
}
General
RSS for tagExplore 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
I have created an iOS 18 Control Center Widget that launches my app. However I am not able to detect it in AppDelegate.swift. I have created custom scheme funRun://beginRun in Target => Info => URL Types URL Types setup in Xcode
This method in AppDelegate.swift does not fire at all and I get this error in console:
Failed to open URL runFun://beginRun: Error Domain=NSOSStatusErrorDomain Code=-10814 "(null)" UserInfo={_LSLine=279, _LSFunction=-[_LSDOpenClient openURL:fileHandle:options:completionHandler:]}``
`
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
// this does not fire
print("Scheme \(url.scheme)")
print("Host \(url.host)")
return true
}`
I tried this answer to no avail: iOS 18 Control Widget that opens a URL
Even adding EnvironmentValues().openURL(url) as suggested here did not help.
@MainActor
func perform() async throws -> some IntentResult & OpensIntent {
let url = URL(string: "funRun://beginRun")!
EnvironmentValues().openURL(url)
return .result(opensIntent: OpenURLIntent(url))
}
Here is my extension code: My goal is to detect the url string from the request, so I can decide which screen to launch from AppDelegate's open url method. When I test this with iOS 18 RC it does not work either in simulator or on real device
import AppIntents
import SwiftUI
import WidgetKit
@available(iOS 18.0, watchOS 11.0, macOS 15.0, visionOS 2.0, *)
struct StartRunControl: ControlWidget {
var body: some ControlWidgetConfiguration {
StaticControlConfiguration(
kind: "name.funRun.StartRun",
provider: Provider()
) { value in
ControlWidgetButton("Hello",
action: MyIntent()) { hi in
Label("Start", systemImage: "sun.min.fill")
}
}
.displayName("Start run")
.description("Opens a run screen.")
}
}
@available(iOS 18.0, watchOS 11.0, macOS 15.0, visionOS 2.0, *)
extension StartRunControl {
struct Provider: ControlValueProvider {
var previewValue: Bool {
false
}
func currentValue() async throws -> Bool {
let isRunning = true // Check if the timer is running
return isRunning
}
}
}
@available(iOS 18.0, watchOS 11.0, macOS 15.0, visionOS 2.0, *)
struct MyIntent: AppIntent {
static let title: LocalizedStringResource = "My Intent"
static var openAppWhenRun: Bool = true
init() {}
@MainActor
func perform() async throws -> some IntentResult & OpensIntent {
let url = URL(string: "funRun://beginRun")!
EnvironmentValues().openURL(url)
return .result(opensIntent: OpenURLIntent(url))
}
}
I even checked info.plist and it seems okay.
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>beginRun</string>
<key>CFBundleURLSchemes</key>
<array>
<string>funRun://beginRun</string>
</array>
</dict>
</array>
Does anyone know where the problem might be? Thanks!
With the newest iPad Pro and iPad Air's, the front facing camera sits on the long horizontal edge, which is different from the previous version which had the camera on the shorter top edge. We have an app that needs to put a UI item near the camera. Is there a way of detecting where the front facing camera is on iOS?
I have tried doing simple resolution checks, i.e,
if width == ipadProWidth || width == ipadAirWidth {
do2024iPadProLayout()
} else {
doStandardiPadLayout()
}
But this doesn't feel like the nicest way to do this check, because it's liable to break moving forward, and theres the possibility Apple release more devices with the camera on the horizontal edge.
Any help here is appreciated!
I'm building a MacOS app which reads a lot of PDFs in the background. Some of these PDF's have an embedded font which is not installed on the system. In such cases the app shows a popup asking whether to Download or Skip the font. This seems to be a PDFKit behavior because I see the same behavior when I open the file in Preview (see screenshot)
This behavior is disruptive to the user experience and I'd like to be able to disable font downloads. However I don't see any option in the PDFKit API to do so. Any ideas?
My app needs to send iMessages with an attached data file. The view comes up modally and the user needs to press the send button. When the button is tapped the error occurs and the attachment and message is not delivered.
I have tried three implementations of UIViewControllerRepresentable for MFMessageComposeViewController that have worked for iOS 15 and 16, but not 17. If I make the simplest app to show the problem, it will reliably fail on all iOS versions tested.
If I remove the attachment, the message gets sent. In contrast, the equivalent UIViewControllerRepresentable for email works perfectly every time. After struggling for weeks to get it to work, I am beginning to believe this is a timing error in iOS. I have even tried unsuccessfully to include dispatch queue delays.
Has anybody else written a swiftUI based app that can reliably attach a file to an iMessage send?
UIViewControllerRepresentable:
import SwiftUI
import MessageUI
import UniformTypeIdentifiers
struct AttachmentData: Codable {
var data:Data
var mimeType:UTType
var fileName:String
}
struct MessageView: UIViewControllerRepresentable {
@Environment(\.presentationMode) var presentation
@Binding var recipients:[String]
@Binding var body: String
@Binding var attachments:[AttachmentData]
@Binding var result: Result<MessageComposeResult, Error>?
func makeUIViewController(context: Context) -> MFMessageComposeViewController {
let vc = MFMessageComposeViewController()
print("canSendAttachments = \(MFMessageComposeViewController.canSendAttachments())")
vc.recipients = recipients
vc.body = body
vc.messageComposeDelegate = context.coordinator
for attachment in attachments {
vc.addAttachmentData(attachment.data, typeIdentifier: attachment.mimeType.identifier, filename: attachment.fileName)
}
return vc
}
func updateUIViewController(_ uiViewController: MFMessageComposeViewController, context: Context) {
}
func makeCoordinator() -> Coordinator {
return Coordinator(presentation: presentation, result: $result)
}
class Coordinator: NSObject, MFMessageComposeViewControllerDelegate {
@Binding var presentation: PresentationMode
@Binding var result: Result<MessageComposeResult, Error>?
init(presentation: Binding<PresentationMode>, result: Binding<Result<MessageComposeResult, Error>?>) {
_presentation = presentation
_result = result
}
func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) {
defer {
$presentation.wrappedValue.dismiss()
}
switch result {
case .cancelled:
print("Message cancelled")
self.result = .success(result)
case .sent:
print("Message sent")
self.result = .success(result)
case .failed:
print("Failed to send")
self.result = .success(result)
@unknown default:
fatalError()
}
}
}
}
SwiftUI interface:
import SwiftUI
import MessageUI
struct ContentView: View {
@State private var isShowingMessages = false
@State private var recipients = ["4085551212"]
@State private var message = "Hello from California"
@State private var attachment = [AttachmentData(data: Data("it is not zip format, however iMessage won't allow the recipient to open it if extension is not a well-known extension, like .zip".utf8), mimeType: .zip, fileName: "test1.zip")]
@State var result: Result<MessageComposeResult, Error>? = nil
var body: some View {
VStack {
Button {
isShowingMessages.toggle()
} label: {
Text("Show Messages")
}
.sheet(isPresented: $isShowingMessages) {
MessageView(recipients: $recipients, body: $message, attachments: $attachment, result: $result)
}
.onChange(of: isShowingMessages) { newValue in
if !isShowingMessages {
switch result {
case .success(let type):
switch type {
case .cancelled:
print("canceled")
break
case .sent:
print("sent")
default:
break
}
default:
break
}
}
}
}
}
}
#Preview {
ContentView()
}
Before iPadOS 18, I was using hidesBottomBarWhenPushed, and it worked beautifully.
Now, it's broken/not working.
How are we supposed to hide the new tab bar nowadays?
I am looking to use the iOS share sheet in my app where the user can send an invite link to friends, however I want to limit the number of times they can do this.
Is it possible to limit the number of recipients who you can share an item using the share sheet, or if there any sort of post-feedback sent from the share sheet back to the app once the share sheet is closed?
ERROR ITMS-90349: "Invalid Info.plist value. The value of the EXExtensionPointldentifier key, com.apple.contact.provider.extension, in the Info.plist of "MainApp.app/Extensions/ContactProviderExtension.appex" is invalid.
We were working on new iOS18 Contacts Provider extension and when try to test the feature in testflight we were unable to submit the build and getting the above error. The extensionPointldentifier 'com.apple.contact.provider.extension' was auto generated by xcode and apple doc mentioned the same value to use for Contacts Provider extension support. But it is not accepting in testflight.
https://developer.apple.com/documentation/contactprovider/contactproviderextension
Any help will be appreciated.
In my Swift app for MacOS, I used to set the app icon in status bar with following logic.
If dark mode is enabled, white colour template icon
If light mode is enabled, black colour template icon
Until BigSur with this configuration, if the background wallpaper color was changed being in the same display mode, the status bar icon color used to change dynamically.
From Ventura onwards, it does not depend on the background colour anymore with same configuration in the code.
Can someone please help here?
Hi,
My iOS app shows more language with region codes than what I've selected in Xcode:
This is what I see in the language selection (simulator and device):
How can I remove all the language with region codes? I want to remove:
English (US)
Suomi (Suomi)
Deutsch (Deutschland)
Kalaallisut (Kalaallit Nunaat)
Norsk bokmål (Norge)
Thank you!
Hello everyone, I’m currently developing an app for the Apple Watch and am working on implementing a dimming feature that activates when the device is in Theater mode.
Is there any way to detect programmatically whether Theater mode is enabled or disabled? Thanks!
As the new feature is launched I also want to make user experience smoother in my app using the AccessorySetupKit. But my peripheral is not discoverable. But another ios device with same advertisement data is discoverable by AccessorySetupKit. I didn't find much information on the documents related to the third party connection. I'm not sure if the third party peripheral should be MFI supported or anything else is required.
Is there anything I'm missing here to fullfill the requirement, please let me know.
Below is the code i"m using to discover the peripheral. Once again iOS to iOS discovery is working, facing issue with third party peripheral is not discovering.
private var session = ASAccessorySession()
var pickerDismissed = true
private static let perepheral: ASPickerDisplayItem = {
let descriptor = ASDiscoveryDescriptor()
descriptor.bluetoothServiceUUID = PublisherClass.serviceUUID
return ASPickerDisplayItem(
name: "Test_Name",
productImage: UIImage(named: "sample")!,
descriptor: descriptor
)
}()
override func viewDidLoad() {
super.viewDidLoad()
self.session.activate(on: DispatchQueue.main, eventHandler: handleSessionEvent(event:))
}
@IBAction func presentPicker() {
session.showPicker(for: [Self.perepheral]) { error in
if let error {
print("Failed to show picker due to: \(error.localizedDescription)")
}
}
}
private func handleSessionEvent(event: ASAccessoryEvent) {
switch event.eventType {
case .accessoryAdded, .accessoryChanged:
guard let accessory = event.accessory else { return }
print("\(accessory)")
case .activated:
guard let accessory = session.accessories.first else { return }
print("\(accessory)")
case .accessoryRemoved:
print("Received event type accessoryRemoved)")
case .pickerDidPresent:
pickerDismissed = false
case .pickerDidDismiss:
pickerDismissed = true
default:
print("Received event type \(event.eventType)")
}
}
}
I also added these details in plist
NSAccessorySetupKitSupports
Bluetooth
NSAccessorySetupBluetoothServices
XCode version: Version 14.2
Ios: 17.6.1
ios versions younger than 17 perform normally。
like this
This code can open app, but the deep link is not send to the app.
It doesn't seem to call the UIApplicationDelegate's "application(_:open:options:)" method, so I can't read the link string that was passed in
func perform() async throws -> some IntentResult & OpensIntent {
guard let url = URL(string: "myapp://myappintent") else {
// throw an error of your choice here
}
return .result(opensIntent: OpenURLIntent(deepLink))
}
I am developing SDK and swizzling viewDidAppear.
I have a customer who implements a custom TabBar Navigation where VC's are added to the hierarchy on the first load, and then, he changes the opacity to the currently displayed tab so the next time the user sees the tab - viewDidAppear isn't called, so my code isn't called.
I'm attaching a sample project which reproduces that.
Is there any way to trigger ViewDidAppear intentionally?
If yes, what can be the side effect of doing that?
Do I have any other alternative in this case?
@main
struct DemoCustomTabViewApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
TabBarRouterView()
}
}
}
import UIKit
// MARK: - TabBarItem (unchanged)
enum TabBarItem: Identifiable, CaseIterable {
case home, search, profile
var id: Self { self }
var title: String {
switch self {
case .home: return "Home"
case .search: return "Search"
case .profile: return "Profile"
}
}
var icon: String {
switch self {
case .home: return "house"
case .search: return "magnifyingglass"
case .profile: return "person"
}
}
}
// MARK: - NavigationControllerView
struct NavigationControllerView: UIViewControllerRepresentable {
var rootViewController: UIViewController
func makeUIViewController(context: Context) -> UINavigationController {
let navigationController = UINavigationController(rootViewController: rootViewController)
return navigationController
}
func updateUIViewController(_ uiViewController: UINavigationController, context: Context) {}
}
// MARK: - TabBarRouterViewModel
class TabBarRouterViewModel: ObservableObject {
@Published var currentTab: TabBarItem = .home
@Published var cachedViews: [TabBarItem: AnyView] = [:]
let tabs: [TabBarItem] = TabBarItem.allCases
func switchTab(to tab: TabBarItem) {
currentTab = tab
}
func createView(for tab: TabBarItem) -> AnyView {
if let cachedView = cachedViews[tab] {
return cachedView
}
let rootViewController: UIViewController
switch tab {
case .home:
rootViewController = UIHostingController(rootView: Text("Home View"))
case .search:
rootViewController = UIHostingController(rootView: Text("Search View"))
case .profile:
rootViewController = UIHostingController(rootView: Text("Profile View"))
}
let navigationView = NavigationControllerView(rootViewController: rootViewController)
let anyView = AnyView(navigationView)
cachedViews[tab] = anyView
return anyView
}
}
// MARK: - CustomTabBarView (unchanged)
struct CustomTabBarView: View {
let tabs: [TabBarItem]
@Binding var selectedTab: TabBarItem
let onTap: (TabBarItem) -> Void
var body: some View {
HStack {
ForEach(tabs) { tab in
Spacer()
VStack {
Image(systemName: tab.icon)
.font(.system(size: 24))
Text(tab.title)
.font(.caption)
}
.foregroundColor(selectedTab == tab ? .blue : .gray)
.onTapGesture {
onTap(tab)
}
Spacer()
}
}
.frame(height: 60)
.background(Color.white)
.shadow(radius: 2)
}
}
// MARK: - TabBarRouterView
struct TabBarRouterView: View {
@StateObject private var viewModel = TabBarRouterViewModel()
var body: some View {
VStack(spacing: .zero) {
contentView
CustomTabBarView(
tabs: viewModel.tabs,
selectedTab: $viewModel.currentTab,
onTap: viewModel.switchTab
)
}
.edgesIgnoringSafeArea(.bottom)
}
private var contentView: some View {
ZStack {
ForEach(viewModel.tabs) { tab in
viewModel.createView(for: tab)
.opacity(viewModel.currentTab == tab ? 1.0 : 0.0)
}
}
}
}
I have a .Net MAUI App.
As soon as i close the app or put in the background the app crashes instantly. It only happens on
OS version: iPad OS 17.5.1
Model:iPad mini (6th generation).
Below is the exception logged on firebase crashlytics
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UIGraphicsBeginImageContext() failed to allocate CGBitampContext: size={0, 0}, scale=3.000000, bitmapInfo=0x2002. Use UIGraphicsImageRenderer to avoid this assert.'
Any suggestions or ideas ?
In my app I added an AppIcon in the Assets.xcassets folder. I added a any/dark/tinted version of the app icon, in 1024x1024 resolution as a HEIC file, specifying a "single size" iOS option.
When I build and run the app in xcode16 beta on iOS18 the icon works as expected, but when I run the same app on iOS17 the icon just shows up as a black rectangle.
How do I get the app icon to work correctly on both iOS18 and iOS17?
Hi All,
I'm very new to iOS development and Swift UI is my first coding language. I'm trying to link the users search results in Spotlight with the detail view that is stored in Core Data. I can search for users data in spotlight but when I tap on it, it's only appearing in the main view of the app. Is there anyways that I can use .onContinueUserActivity at the launch of the app or is there any different code that I have to use? I've searched for many articles but I couldn't get a solution. It would be good if anyone can share some links or guide here. Thank you.
.onContinueUserActivity(DetailView.productUserActivityType) { userActivity in
if let product = try? userActivity.typedPayload(Product.self) {
selectedProduct = product.id.uuidString
}
}
I get this code from Apple's State restoration app but I can't use this with Core Data.
I've noticed the tab bar in tvOS 18 (beta) is positioned lower on the TV screen than in previous versions. Bug? I see no documentation on this important UI change...
If this is not a bug, is there any way to adjust the y coordinate of the tab bar location in tvOS 18? I would really like to restore this to the previous location for my app and avoid having to do OS-conditional constraints for all my views/pages.
My app correctly applies the ShieldConfiguration template that I chose (icon, text, CTA, etc), but some users reported seeing the following default shield:
With the default shield text that reads, "You cannot use AppName because it is restricted."
Any idea why?