Discuss Swift.

Swift Documentation

Post

Replies

Boosts

Views

Activity

Opening an App Conditionally with Swift and App Intents in iOS Shortcuts
I am trying to create a simple app that "blocks" other apps if a certain condition is not met. I am currently using the IOS shortcuts and have set up an automation that opens my app A whenever another app B opens. If the condition is not met i imagine the flow to look like: Open app A. My app B opens instead. I check a box in my app B. I navigate back to app A and it works as expected. If the condition already is met the app A would work as expected from the beginning. What is have tried so far My first attempt involved using an AppIntent and changing the openAppWhenRun programmatically based on the condition. I did however learn pretty quickly that changing the value of openAppWhenRun does not change if the AppIntent actually opens my app. The code for this looked like this where the value of openAppWhenRun is changed in another function. struct BlockerIntent: AppIntent { static let title: LocalizedStringResource = "Blocker App" static let description: LocalizedStringResource = "Blocks an app until condition is met" static var openAppWhenRun: Bool = false @MainActor func perform() async throws -> some IntentResult { return .result() } } Another attempt involved setting openAppWhenRun to false in an outer AppIntent and opening another inner AppIntent if the condition is met. If the condition in my app is met openAppWhenRun is set to true and instead of opening the inner AppIntent an Error is thrown. This functions as expected but there is an error notification showing every time I open the "blocked" app. struct BlockerIntent: AppIntent { static let title: LocalizedStringResource = "Blocker App" static let description: LocalizedStringResource = "Blocks an app until condition is met" static var openAppWhenRun: Bool = false func perform() async throws -> some IntentResult & OpensIntent { if (BlockerIntent.openAppWhenRun) { throw Error.notFound } return .result(opensIntent: OpenBlockerApp()) } enum Error: Swift.Error, CustomLocalizedStringResourceConvertible { case notFound var localizedStringResource: LocalizedStringResource { switch self { case .notFound: return "Ignore this message" } } } } struct OpenBlockerApp: AppIntent { static let title: LocalizedStringResource = "Open Blocker App" static let description: LocalizedStringResource = "Opens Blocker App" static var openAppWhenRun: Bool = true @MainActor func perform() async throws -> some IntentResult { return .result() } } My third attempt look similar to the previous one but instead I used two different inner AppIntents. The only difference between the two were that on had openAppWhenRun = false and the other had openAppWhenRun = true. struct BlockerIntent: AppIntent { static let title: LocalizedStringResource = "Blocker App" static let description: LocalizedStringResource = "Blacks an app until condition is met" static var openAppWhenRun: Bool = false func perform() async throws -> some IntentResult & OpensIntent { if (BlockerIntent.openAppWhenRun) { return .result(opensIntent: DoNotOpenBlockerApp()) } else { return .result(opensIntent: OpenBlockerApp()) } } } Trying this gives me this error: Function declares an opaque return type 'some IntentResult & OpensIntent', but the return statements in its body do not have matching underlying types I have also tried opening the app with a URL link with little to no success often ending up in an infinity loop, I did try the ForegroundContinuableIntent but it did not function as expected since it relies on the users input. Is there any way to do what I am trying to accomplish? I have seen other apps using a similar concept so I feel like this should be possible. Many thanks!
5
5
1.5k
Nov ’23
Xcode 15.1 & iOS 17.2: SwiftData ModelContext Delete: It's only possible to delete the data after it has been inserted for about 30 seconds
I'm a newbie in working with SwiftData and I hope for your help in solving the below issue :") It's about deleting the objects into a Model by ModelContext.delete(). It's only possible to delete the data after it has been inserted for about 30 seconds. Just run the source code below, tap on "Add" button to add some samples, and then tap on "Delete" button right away. At this time, Delete action doesn't work. You have to wait about 30 seconds, then tap on "Delete" button, it will work - the sample data are deleted properly. I tested this issue on Xcode 15.1 beta (15C5042i) and found that: This issue always happens on Preview w/ iOS 17 or iOS 17.2. This issue doesn't happen on Simulator w/ iOS 17 BUT it happens on Simulator w/ iOS 17.2 Is this an issue of iOS 17.2 ? Full source code on GitHub Bike.swift import Foundation import SwiftData @Model class Bike { var name: String init(name: String) { self.name = name } } TestApp.swift import SwiftUI import SwiftData @main struct TestApp: App { var body: some Scene { WindowGroup { BikeListView() } .modelContainer(for: Bike.self) } } BikeListView.swift import SwiftUI import SwiftData struct BikeListView: View { @Environment(\.modelContext) var modelContext @Query var bikes: [Bike] var body: some View { VStack { HStack(spacing: 30) { Button { addSamples() } label: { Text("Add") } Button { deleteSamples() } label: { Text("Delete") } } List { ForEach(bikes) { eachBike in Text(eachBike.name) } } } } func addSamples() { let bikeOne = Bike(name: "One") let bikeTwo = Bike(name: "Two") modelContext.insert(bikeOne) modelContext.insert(bikeTwo) } func deleteSamples() { try? modelContext.delete(model: Bike.self) } } #Preview { do { let modelConfig = ModelConfiguration(isStoredInMemoryOnly: false) let modelContainer = try ModelContainer(for: Bike.self, configurations: modelConfig) return BikeListView() .modelContainer(modelContainer) } catch { fatalError("Content View's Preview") } } Thanks for reading and I'm looking forward to your help.
2
0
1.2k
Nov ’23
startAccessingSecurityScopedResource always returns false for files in iCloud Drive folder
Hello, I am trying to use the SwiftUI fileImporter to get the URL of a direcotry and access it for the files in it. If I follow the document( Access the directory’s content ) and use url.startAccessingSecurityScopedResource for each file, it always returns false. but this seems to be different from the documentation. If the current behavior is correct, will the documentation be updated in the future? Related: Access all files in UIDocumentPick… | Apple Developer Forums I asked this question because I am concerned that if I remove the standardAccessingSecurityScopedResource to match the current situation, the standardAccessingSecurityScopedResource may become necessary due to future iOS updates. Also, is there any way to know if the status of the AccessingSecurityScopedResource? It would be helpful if we could callstartAcesingSecurityScopedResource only when needed. Thanks Here is a sample code @main struct SampleApp: App { var body: some Scene { WindowGroup { ContentView() } } } struct ContentView: View { @State private var isShowingImportFolder = false @State private var isShowingImportFile = false var body: some View { VStack(spacing: 48) { Button("Read Folder") { isShowingImportFolder = true } .fileImporter(isPresented: $isShowingImportFolder, allowedContentTypes: [.folder]) { result in switch result { case .success(let url): processDirectory(url) case .failure(let error): print("failed. error: \(error)") } } Button("Read File") { isShowingImportFile = true } .fileImporter(isPresented: $isShowingImportFile, allowedContentTypes: [.data]) { result in switch result { case .success(let url): readFile(url) case .failure(let error): print("failed. error: \(error)") } } } } private func processDirectory(_ directory: URL) { guard directory.startAccessingSecurityScopedResource() else { fatalError("failed. directory.startAccessingSecurityScopedResource") } defer { directory.stopAccessingSecurityScopedResource() } var error: NSError? NSFileCoordinator().coordinate(readingItemAt: directory, error: &error) { url in let urls = try! FileManager.default.contentsOfDirectory(at: url, includingPropertiesForKeys: [.nameKey, .isDirectoryKey]) urls.lazy .filter { !$0.hasDirectoryPath } .forEach { readFile($0) } } } private func readFile(_ url: URL) { guard url.startAccessingSecurityScopedResource() else { print("failed access. \(url.path)") return } defer { url.stopAccessingSecurityScopedResource() } let data = try! Data(contentsOf: url) print("file.path: \(url.path()), size: \(data.count)") // read file... } }
1
0
1.1k
Nov ’23
Issue starting Live Activities with ActivityKit push notifications
Hi all, I'm trying to implement starting Live Activities with push notifications according to this article: https://developer.apple.com/documentation/activitykit/starting-and-updating-live-activities-with-activitykit-push-notifications I'm using Xcode 15.1 beta 3, I have run my tests on a physical device with iOS 17.2 as well as the simulator with iOS 17.2 My problem is I can't seem to be able to get the pushToStartToken needed to start the live activities. I have subscribed to the pushToStartTokenUpdates but I never get any updates. Here is the code I used: Task { do { for try await data in Activity<DailyGoalActivityAttributes>.pushToStartTokenUpdates { let token = data.map {String(format: "%02x", $0)}.joined() print("Activity token: \(token)") } } catch { print(error) } } Any help would be greatly appreciated. Thanks, HS
12
5
5.6k
Nov ’23
Unable to verify App
While using the application, it suddenly quits. When we attempt to reopen it, an error pop-up appears stating, 'Unable to verify app. Internet connection is required to verify trust.' We tried accessing the VPN and regularity options in settings, and clicked on 'Trust,' but it was ineffective. The only solution that works is resetting the iPad. However, after one or two days, the same issue arises again. This problem seems to occur exclusively on certain iPads. What might be causing this recurring problem?"
6
2
2.7k
Nov ’23
Is it safe to call low level Darwin function on FileHandle?
I have the following code: extension FileHandle { func readInto(_ buffer: inout [UInt8]) -> Int { buffer.withUnsafeMutableBytes { Darwin.read(fileDescriptor, $0.baseAddress, $0.count) } } } It can compile, but I wonder if this is supported since it's code in an app that is going to be submitted to App Store. The reason I don't use read(upToCount:) or readData(ofLength:) is that I am reading possibly very large files by small chunks and don't want to let Swift runtime allocate small buffers repeatedly.
0
0
245
Nov ’23
Xcode Lag Issue When Using Custom rawValue in Enum
I've encountered a performance issue in Xcode related to the use of a custom rawValue in enums. When attempting to create a variable using rawValue as its name inside the enum, Xcode exhibits significant lag and performance degradation. This only use to happen in medium to large projects. Steps to Reproduce: Define an enum with a custom rawValue property. Navigate through your codebase, especially in models. enum Example { case test1, test2, test3 var rawValue: Int { 0 } } Renaming rawValue into anything else solves the issue. It's possible that Xcode has optimizations or behaviors associated with certain conventional names, such as rawValue.
0
1
246
Nov ’23
SwiftData @Model Codable conformance for array of structs
I have a struct that is identifiable, and has two String variables and a UUID. I am using @Model decorator/macro for a class I want to persist, which has a few String variables (with values assigned to them), and some arrays of my struct, which are assigned values with the init() initialiser. This class also has two functions, both of which return an integer. I am getting many errors for the String variables and initialisation of the arrays of structs: Referencing instance method 'setValue(forKey:to:)' on 'Array' requires that 'Record' conform to 'PersistentModel' No exact matches in call to instance method 'setValue' No exact matches in call to instance method 'getValue' I tried converting the struct to class, but that did not help. I also tried writing my own encoder and decoder functions, but that did not help either. // Created by Devansh Trivedi on 24/11/23. // import SwiftUI // For UUID() to make Record struct Identifiable import SwiftData struct Record : Identifiable { var date: String var value: String var id = UUID() } @Model class Card { //https://www.donnywals.com/making-your-swiftdata-models-codable/ // enum CodingKeys: CodingKey { // case unit, date, name // } // required init(from decoder: Decoder) throws { // let container = try decoder.container(keyedBy: CodingKeys.self) // self.unit = try container.decode(String.self, forKey: .unit) // self.date = try container.decode(String.self, forKey: .date) // self.name = try container.decode(String.self, forKey: .name) // } // func encode(to encoder: Encoder) throws { // var container = encoder.container(keyedBy: CodingKeys.self) // try container.encode(unit, forKey: .unit) // try container.encode(date, forKey: .date) // try container.encode(date, forKey: .name) // } var unit:String="Liters" var date:String="Nov 23" var name:String="Milk" var column_1:[Record] var column_2:[Record] var column_3:[Record] init() { self.column_1 = [ Record(date: "1", value: ""), Record(date: "2", value: ""), Record(date: "3", value: ""), Record(date: "4", value: ""), Record(date: "5", value: ""), Record(date: "6", value: ""), Record(date: "7", value: ""), Record(date: "8", value: ""), Record(date: "9", value: ""), Record(date: "10", value: "") ] self.column_2 = [ Record(date: "11", value: ""), Record(date: "12", value: ""), Record(date: "13", value: ""), Record(date: "14", value: ""), Record(date: "15", value: ""), Record(date: "16", value: ""), Record(date: "17", value: ""), Record(date: "18", value: ""), Record(date: "19", value: ""), Record(date: "20", value: "") ] self.column_3 = [ Record(date: "21", value: ""), Record(date: "22", value: ""), Record(date: "23", value: ""), Record(date: "24", value: ""), Record(date: "25", value: ""), Record(date: "26", value: ""), Record(date: "27", value: ""), Record(date: "28", value: ""), Record(date: "29", value: ""), Record(date: "30", value: ""), Record(date: "31", value: "") ] } func total() -> Int { // https://hoyelam.com/summing-up-numeric-properties-of-objects-in-an-array-in-swift/ // https://dev.to/hoyelam/summing-up-numeric-properties-of-objects-in-an-array-in-swift-4og return column_1.lazy .filter( { !$0.value.isEmpty } ) .map( { Int($0.value)! } ) .reduce(0, +) + column_2.lazy .filter( { !$0.value.isEmpty } ) .map( {Int($0.value)! }) .reduce(0, +) + column_3.lazy .filter({!$0.value.isEmpty}) .map( {Int($0.value)! }) .reduce(0, +) } func bill() -> Int { return self.total()*65 } }
2
2
1.6k
Nov ’23
Is there an opposite of @available?
I got tried of the compiler telling me that .onChange(of:) was deprecated, so I thought, find, I'll simply stub it out for the older versions. Only... I can't seem to do that? I can use @available(macOS 14, *) to build for that and later, but is there any way to do the opposite? (I'd hoped there was a #if available support, but there isn't.)
4
0
652
Nov ’23
Encoding struct optional field to JSON
Hi! I having trouble with encoding optional field of structure to send it to my server. Here's this struct: struct Defect: Codable { var type: String = "" var count: Int? = nil } When server returns data like this [["type": "SOME_TYPE_1"], ["type": "SOME_TYPE_2", "count": 2]] app successfully decodes is, but when I'm trying to encode the same data with func request(json: Dictionary<String, Any> = [:]) { // some code ... request.httpBody = try JSONSerialization.data(withJSONObject: json) // some other code ... } func updateObject(defects: Array<Defect>) { // some code ... let json: [String: Any] = ["comment": comment, "defects": defects] request(/*some params*/ json: json) // some code ... } I got error NSException * "Invalid type in JSON write (__SwiftValue)" in this string: request.httpBody = try JSONSerialization.data(withJSONObject: json) Struct's fields values at this moment are: json["defects"][0].type = "SOME_TYPE_1" json["defects"][0].count = nil json["defects"][1].type = "SOME_TYPE_2" json["defects"][1].count = 2 Please give me a guidance how to solve this problem. Maybe using of encode(to:) may help me (I'm novice, and didn't try it yet).
2
0
550
Nov ’23
Unexpected behaviour using URL.hasDirectory and URL.isFileURL
URL.hasDirectory and URL.isFileURL are reporting a directory url (such as this: file:///Users/user/Pictures/Test/Imports ) to be a "file". I get this in my logs: url: file:///Users/user/Pictures/Test/Imports hasDirectoryPath: false isFile: true Is this caused by the schema being file:/// ? The urls come straight from FileManager.DirectoryEnumerator so I have no control over how the URLs are instantiated. What am I doing wrong? In the meantime, I'll be checking my URLs manually.
1
0
261
Nov ’23
Problem Xcode
I would like to share my experience in learning Swift with you. Recently, I started using Playground as recommended on this website, but I encountered an issue, and I hope you can help me. When running code in Xcode Playground, I face a problem. After the phrase "ready to continue playground," the code does not execute, and I do not receive any errors. It just loads with this message, and that's it. I am confident that my code is syntactically correct, as I follow recommendations and topics presented on this website. The default "Hello, playground" program takes quite a long time to execute. My internet connection is good. I have already tried restarting Xcode, checked the code for errors, and created a new Playground, but the issue persists. Additionally, I have the latest version of Xcode installed. I would appreciate it if you could provide guidance on how to resolve this issue or offer additional recommendations. It is essential for me to continue learning Swift, and your support would be highly valuable.
3
1
333
Nov ’23
Accessing iOS Device Serial Number to Comply with German KassenSichV
Hey there, in order to comply with the German law, especially the KassenSichV for cash register systems it is necessary to access the "manufacturer issued unique device serial number" and log it in the sales history, as well as print it on the receipt for the customer. Is there any way to access the device serial number through .NET Maui, or even Swift? Thank you in advance!
1
0
534
Nov ’23
When modifying the Image color through "onTapGesture", XCode will crash
Hi I am a beginner and I am preparing to make a Tabbar component for use in my practice APP. The component uses Image as the button. When the button is clicked (onTapGesture), I hope that the color in the IMAGE will change, but now When running to onTapGesture, XCode crashes, who knows how to write this code to make it run normally. Thanks class MainViewManager : ObservableObject{ @Published var tabbarStatus : TabbarStatus = .homeView enum TabbarStatus : CaseIterable { case homeView case articsPage case profile var icon : String{ switch self{ case .homeView: return "house" case .articsPage: return "person.2" case .profile: return "person.crop.circle" } } } } struct MainTabbar: View { @EnvironmentObject var vm : MainViewManager @State var btnColor : Color = .gray var body: some View { HStack{ ForEach(MainViewManager.TabbarStatus.allCases, id: \.self) { tabbarItem in //let selected = tabbarItem == vm.tabbarStatus Image(systemName:tabbarItem.icon) .foregroundStyle(btnColor) .onTapGesture { vm.tabbarStatus = tabbarItem btnColor = Color.accentColor } if tabbarItem != .profile { Spacer() } } } .padding(.horizontal,30) .padding(.all) .frame(maxHeight: .infinity ,alignment: .bottom) .background(Color.white) } } #Preview { MainTabbar() }
2
0
223
Nov ’23
Implementing SECP256R1 Signature Matching with Rust's FastCrypto in Swift
Hello fellow developers, I'm currently working on an SDK involving the SECP256R1 standard and facing an interesting issue. My goal is to ensure the Swift implementation of SECP256R1 signatures matches that of Rust's FastCrypto implementation. The Issue: When running tests to compare signatures generated by Swift and Rust implementations, the signatures do not match. Despite this mismatch, verification tests still succeed. I've tried using both the P256 class from CryptoKit and SecKey from the Security SDK. The Swift code is being written in Xcode 15 Beta 8, Swift 5.9. Code Snippet: struct SECP256R1PrivateKey { /// Commented is P256, uncommented is SecKey // public init(key: Data) throws { // if let privateKey = try? P256.Signing.PrivateKey(rawRepresentation: key) { // self.key = privateKey // } else { // throw AccountError.invalidData // } // } public init(key: Data) throws { if let privateKeyP256 = try? P256.Signing.PrivateKey(rawRepresentation: key) { let attributes: [String: Any] = [ kSecAttrKeyClass as String: kSecAttrKeyClassPrivate, kSecAttrKeyType as String: kSecAttrKeyTypeECDSA, kSecAttrTokenID as String: kSecAttrTokenIDSecureEnclave, kSecAttrKeySizeInBits as String: 256 ] var error: Unmanaged<CFError>? guard let privateKey = SecKeyCreateWithData(privateKeyP256.rawRepresentation as CFData, attributes as CFDictionary, &error) else { throw error?.takeRetainedValue() as Error? ?? NSError(domain: NSOSStatusErrorDomain, code: Int(errSecParam), userInfo: nil) } self.key = privateKey } else { throw AccountError.invalidData } } // public func sign(data: Data) throws -> Signature { // let signature = try self.key.signature(for: data) // return Signature( // signature: signature.rawRepresentation, // publickey: try self.publicKey().key.compressedRepresentation, // signatureScheme: .SECP256R1 // ) // } public func sign(data: Data) throws -> Signature { let dataHash = Data(data.sha256) var error: Unmanaged<CFError>? guard let signature = SecKeyCreateSignature(self.key, .ecdsaSignatureMessageX962SHA256, dataHash as NSData, &error) as Data? else { throw error!.takeRetainedValue() as Error } guard let publicKey = SecKeyCopyExternalRepresentation(try self.publicKey().key, &error) as Data? else { throw AccountError.invalidData } return Signature( signature: signature, publickey: publicKey, signatureScheme: .SECP256R1 ) } } func testThatTheRustImplementationForSignaturesIsTheSame() throws { let account = try Account(privateKey: Data(self.validSecp256r1SecretKey), accountType: .secp256r1) guard let signData = "Hello, world!".data(using: .utf8) else { XCTFail("Unable to encode message"); return; } let signature = try account.sign(signData) XCTAssertEqual( try signature.hex(), "26d84720652d8bc4ddd1986434a10b3b7b69f0e35a17c6a5987e6d1cba69652f4384a342487642df5e44592d304bea0ceb0fae2e347fa3cec5ce1a8144cfbbb2" ) } The Core Question: How do I implement the R1 signature in Swift so that it matches the signature generated by Rust's FastCrypto? Any insights, suggestions, or sample code snippets that could guide me in the right direction would be immensely appreciated! Thank you in advance!
4
1
1.3k
Nov ’23