Discuss Swift.

Swift Documentation

Post

Replies

Boosts

Views

Activity

Function called isolated on MainActor via an isolated parameter are not considered run on the MainActor
If I try to compile the following, I get a compilation error: import Foundation func isolatedPrint<A : Actor>(on actor: isolated A) { print("hello") } Task{ @MainActor in isolatedPrint(on: MainActor.shared) } The error: toto.swift:9:2: error: expression is 'async' but is not marked with 'await' isolatedPrint(on: MainActor.shared) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ await toto.swift:9:2: note: calls to global function 'isolatedPrint(on:)' from outside of its actor context are implicitly asynchronous isolatedPrint(on: MainActor.shared) ^ I don’t understand why the compiler does not detect the function is called on the MainActor via the actor parameter.
1
0
242
3w
Ensuring exclusive access to a function in structured concurrency
So our back end manages tokens in a strange way. Whenever we try to request a new access token using our refresh token, it invalidates our old refresh token and returns us with a new access + refresh token. The problem with this is that multiple concurrent network requests can see that a user's access token has expired and try to get a new access token, potentially causing us to get a 401 unauthorized error. Is there any way with structured/unstructured concurrency to ensure that our method for grabbing the access token can only at max be run once at a time? Im assuming the only realistic way would be to do something like this: @MyGlobalActor private var tokenTask: Task<String, any Error>? @MyGlobalActor func getAccessToken() async await -> String { if let tokenTask { return try await tokenTask.value } self.tokenTask = Task<String, any Error> { // refresh access token } let token = try await self.tokenTask!.value self.tokenTask = nil return token }
1
0
211
3w
"Unexpectedly found nil while unwrapping an Optional value" in URL
Before anyone rants and raves about checking documentation - I have spent the last 4 hours trying to solve this issue on my own before asking for help. Coding in Swift is VERY new for me and I'm banging my head against the wall trying to teach myself. I am very humbly asking for help. If you refer me to documentation, that's fine but I need examples or it's going to go right over my head. Teaching myself is hard, please don't make it more difficult. I have ONE swift file with everything in it. import Foundation import Cocoa import Observation class GlobalString: ObservableObject { @Published var apiKey = "" @Published var link = "" } struct ContentView: View { @EnvironmentObject var globalString: GlobalString var body: some View { Form { Section(header: Text("WallTaker for macOS").font(.title)) { TextField( "Link ID:", text: $globalString.link ) .disableAutocorrection(true) TextField( "API Key:", text: $globalString.apiKey ) .disableAutocorrection(true) Button("Take My Wallpaper!") { } } .padding() } .task { await Wallpaper().fetchLink() } } } @main struct WallTaker_for_macOSApp: App { @AppStorage("showMenuBarExtra") private var showMenuBarExtra = true @EnvironmentObject var globalString: GlobalString var body: some Scene { WindowGroup { ContentView() .environmentObject(GlobalString()) } // MenuBarExtra("WallTaker for macOS", systemImage: "WarrenHead.png", isInserted: $showMenuBarExtra) { // Button("Refresh") { //// currentNumber = "1" // } // Button("Love It!") { //// currentNumber = "2" // } // Button("Hate It!") { //// currentNumber = "3" // } // Button("EXPLOSION!") { // // currentNumber = "3" // } //// // } } } class Wallpaper { var url: URL? = nil var lastPostUrl: URL? = nil let mainMonitor: NSScreen init() { mainMonitor = NSScreen.main! } struct LinkResponse: Codable { var post_url: String? var set_by: String? var updated_at: String } struct Link { var postUrl: URL? var setBy: String var updatedAt: Date } func parseIsoDate(timestamp: String) -> Date? { let formatter = DateFormatter() formatter.locale = Locale(identifier: "en_US_POSIX") formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" return formatter.date(from: timestamp) } func fetchLink() async { do { url = URL(string: GlobalString().link) let (data, _) = try await URLSession.shared.data(from: url!) let decoder = JSONDecoder() let linkResponse = try decoder.decode(LinkResponse.self, from: data) let postUrl: URL? = linkResponse.post_url != nil ? URL(string: linkResponse.post_url!) : nil let date = parseIsoDate(timestamp: linkResponse.updated_at) let link = Link( postUrl: postUrl, setBy: linkResponse.set_by ?? "anon", updatedAt: date ?? Date() ) try update(link: link) } catch { } } func update(link: Link) throws { guard let newPostUrl = link.postUrl else { return } if (newPostUrl != lastPostUrl) { lastPostUrl = newPostUrl let tempFilePath = try getTempFilePath() try downloadImageTo(sourceURL: newPostUrl, destinationURL: tempFilePath) try applyWallpaper(url: tempFilePath) } else { } } private func applyWallpaper(url: URL) throws { try NSWorkspace.shared.setDesktopImageURL(url, for: mainMonitor, options: [:]) } private func getTempFilePath() throws -> URL { let directory = NSTemporaryDirectory() let fileName = NSUUID().uuidString let fullURL = NSURL.fileURL(withPathComponents: [directory, fileName])! return fullURL } private func downloadImageTo(sourceURL: URL, destinationURL: URL) throws { let data = try Data(contentsOf: sourceURL) try data.write(to: destinationURL) } } The 'fetchLink' function is where things explode, specifically when setting the URL. I do not know what I'm doing wrong.
5
0
381
May ’24
Swift: Declaration name is not covered by macro
Hello! I'm trying to generate a protocol dependent for another one using Swift macros. The implementation looks like the following: @attached (peer, names: suffixed (Dependent),prefixed (svc)) public macro dependableService() = #externalMacro (module: "Macros", type: "DependableServiceMacro") public struct DependableServiceMacro: PeerMacro { public static func expansion (of node: AttributeSyntax, providingPeersOf declaration: some DeclSyntaxProtocol, in context: some MacroExpansionContext) throws -> [DeclSyntax] { guard let baseProto = declaration.as (ExtensionDeclSyntax.self) else { return [] } let nm = baseProto.extendedType.trimmedDescription let protoNm = nm + "Dependent" let varNm = "svc" + nm let protoDecl: DeclSyntax = """ protocol \(raw: protoNm) : ServiceDependent { var \(raw: varNm) : \(raw: nm) { get set } } """ return [protoDecl] } } When I try using it in my code like this @dependableService extension MyService {} the macro correctly expands to the following text: protocol MyServiceDependent : ServiceDependent { var svcMyService : MyService { get set } } However, the compiler gives me the error: error: declaration name 'MyServiceDependent' is not covered by macro 'dependableService' protocol MyServiceDependent : ServiceDependent { ^ Do I understand correctly, that for some reason the compiler cannot deduce the name of the generated protocol based on the name of the extensible protocol, despite the presence of the names: suffixed(Dependent) attribute in the macro declaration? Could anybody please tell me what I'm doing wrong here? Thanks in advance
1
0
275
May ’24
SwiftData does not retrieve my inverse one-to-many Relationship
Here is my models: import SwiftData @Model final public class FirstModel { let name: String @Relationship(deleteRule: .cascade, inverse: \SecondModel.parent) var children = [SecondModel]() init(name: String) { self.name = name } } @Model final public class SecondModel { let parent: FirstModel let name: String @Relationship(deleteRule: .cascade, inverse: \ThirdModel.parent) var children = [ThirdModel]() init(name: String, parent: FirstModel) { self.name = name self.parent = parent } } @Model final public class ThirdModel { let parent: SecondModel let name: String init(name: String, parent: SecondModel) { self.name = name self.parent = parent } } Then I create my model entries: let schema = Schema([ FirstModel.self, SecondModel.self, ThirdModel.self ]) let container = try ModelContainer(for: schema) let context = ModelContext(container) let firstModel = FirstModel(name: "my first model") let secondModel = SecondModel(name: "my second model", parent: firstModel) let thirdModel = ThirdModel(name: "my third model", parent: secondModel) context.insert(firstModel) context.insert(secondModel) context.insert(thirdModel) try context.save() I want to retrieve the children from my models: print("-- Fetch Third Model") let thirdFetchDescriptor: FetchDescriptor<ThirdModel> = FetchDescriptor<ThirdModel>(predicate: #Predicate { $0.name == "my third model" }) let thirdModels = try context.fetch(thirdFetchDescriptor) for entry in thirdModels { print(">>> \(entry) - \(entry.parent) - \(entry.parent.parent)") } print("-- Fetch First Model") let firstFetchDescriptor: FetchDescriptor<FirstModel> = FetchDescriptor<FirstModel>(predicate: #Predicate { $0.name == "my first model" }) let firstModels = try context.fetch(firstFetchDescriptor) for entry in firstModels { print(">>> \(entry) - \(entry.children)") for child in entry.children { print("\t>>> \(child) - \(child.children)") } } ... But it does not seem to work: -- Fetch Third Model >>> cardapart_sdk_app_ui.ThirdModel - cardapart_sdk_app_ui.SecondModel - cardapart_sdk_app_ui.FirstModel -- Fetch First Model >>> cardapart_sdk_app_ui.FirstModel - [] What I would expect to see: -- Fetch First Model >>> cardapart_sdk_app_ui.FirstModel - [cardapart_sdk_app_ui.SecondModel] >>> cardapart_sdk_app_ui.SecondModel - [cardapart_sdk_app_ui.ThirdModel] I am not sure what I am doing wrong or missing...
1
0
296
May ’24
Game Center fetchSavedGames sometimes returns empty list of games, although it works correctly on the next tries
I have implemented the Game Center for authentication and saving player's game data. Both authentication and saving player's data works correctly all the time, but there is a problem with fetching and loading the data. The game works like this: At the startup, I start the authentication After the player successfully logs in, I start loading the player's data by calling fetchSavedGames method If a game data exists for the player, I receive a list of SavedGame object containing the player's data The problem is that after I uninstall the game and install it again, sometimes the SavedGame list is empty(step 3). But if I don't uninstall the game and reopen the game, this process works fine. Here's the complete code of Game Center implementation: class GameCenterHandler { public func signIn() { GKLocalPlayer.local.authenticateHandler = { viewController, error in if let viewController = viewController { viewController.present(viewController, animated: false) return } if error != nil { // Player could not be authenticated. // Disable Game Center in the game. return } // Auth successfull self.load(filename: "TestFileName") } } public func save(filename: String, data: String) { if GKLocalPlayer.local.isAuthenticated { GKLocalPlayer.local.saveGameData(Data(data.utf8), withName: filename) { savedGame, error in if savedGame != nil { // Data saved successfully } if error != nil { // Error in saving game data! } } } else { // Error in saving game data! User is not authenticated" } } public func load(filename: String) { if GKLocalPlayer.local.isAuthenticated { GKLocalPlayer.local.fetchSavedGames { games, error in if let game = games?.first(where: {$0.name == filename}){ game.loadData { data, error in if data != nil { // Data loaded successfully } if error != nil { // Error in loading game data! } } } else { // Error in loading game data! Filename not found } } } else { // Error in loading game data! User is not authenticated } } } I have also added Game Center and iCloud capabilities in xcode. Also in the iCloud section, I selected the iCloud Documents and added a container. I found a simillar question here but it doesn't make things clearer.
0
0
204
May ’24
Weird Swift overriding cocoapods
I don't even use Swift. I use Flutter. I am getting this odd always_embed_swift library warning that seems to be overriding my runner target on xcode. I'll just attach the image down below of what I'm dealing with. Please an apple engineer or someone just help me because this has been a struggle lol. I need to change this but can't find the setting to do so.
0
0
197
May ’24
Storing Different Types of Swift Objects in C++ Using New Interop
Hello Everyone, I'm working on an app that utilizes the new C++ - Swift interop feature. I have a module called ModuleA that contains multiple Swift classes, and I need to store instances of these classes in a C++ class as a class member(to ensure ARC until the class object is deallocated). However, I want to retain the Swift class objects on the stack without directly allocating heap memory from C++. Sample Swift Code: public class SwiftClassA { public init() {} public func FuncA() -&gt; Void { // Perform operations specific to SwiftClassA } } public class SwiftClassB { public init() {} public func FuncA() -&gt; Void { // Perform operations specific to SwiftClassB } } // Additional Swift classes (SwiftClassC to SwiftClassN) follow a similar structure. Sample Cpp Code: CppClass.hpp #include "ModuleA-Swift.h" // Include generated Swift headerclass CppClass { public: // Functions and declarationsprivate: XYZ vClassObject; // Placeholder for Any Swift class object }; CppClass.cpp #include "ModuleA-Swift.h" // Include generated Swift headervoid CppClass::SomeFuncA() noexcept { ModuleA::SwiftClassA obj = ModuleA::SwiftClassA::init(); // Initialize SwiftClassA object vClassObject = obj; // Assign SwiftClassA object to vClassObject } void CppClass::SomeFuncB() noexcept { ModuleA::SwiftClassB obj = ModuleA::SwiftClassB::init(); // Initialize SwiftClassB object vClassObject = obj; // How do I Assign SwiftClassB object to vClassObject? } I'm looking for suggestions on how to efficiently store different types of Swift class objects in my C++ class while maintaining stack-based object retention and proper memory management. Any help or insights would be greatly appreciated. Thanks, Harshal
4
0
373
May ’24
How to use .a in swift with an empty header
I'm making a Swift Program. I got a .a file that builded from some c++ scripts,and I can see some fuctions in it by commed "nm *.a", and a .h file like this My question is how to call the fuctions in .a like "testDebug",I can call from c# like [DllImport("__Internal")] private static extern void testDebug(); Google's answer always with a right .h file,Maybe I should make .h file correct first. Any reply would be greatly appreciated.
2
0
232
May ’24
Regex Builder error message???
I'm debugging some Regex Builder code in my Playground. I run the following piece code: let timeMatchWithout = possibleTime.firstMatch(of: timeWithoutSec) and I get this error message: Regex.Match optional storedCapture contains no some What could this possibly mean? contains no some??? Here is a more complete snippet, if this helps: let hourRef = Reference&lt;Substring&gt;() let minuteRef = Reference&lt;Substring&gt;() let hourReg = Regex { ChoiceOf { Capture(as: hourRef) { One(.digit) One(.digit) } Capture(as: hourRef) { One(.digit) } } } let minuteReg = Regex { ChoiceOf { Capture(as: minuteRef) { One(.digit) One(.digit) } Capture(as: minuteRef) { One(.digit) } } } let ampmRef = Reference&lt;Substring&gt;() let ampmReg = Regex { Capture(as: ampmRef) { ZeroOrMore { ChoiceOf { One("am") One("pm") One("a.m.") One("p.m.") } } } /* transform: { $0.lowercase } */ }.ignoresCase() let timeWithoutSec = Regex { hourReg One(":") minuteReg ZeroOrMore(.whitespace) ampmReg }.ignoresCase() let possibleTime = "10:20 AM" let timeMatchWithout = possibleTime.firstMatch(of: timeWithoutSec) The last line produces the error message. Thanks for the help. Note the removed transform: on the ampmReg definition. If that is included the compiler times out as noted in my previous post, yesterday.
2
0
249
May ’24
Swift Regex Builder issue
Why does this Regex Builder code in my SwiftUI app not work? I'm parsing a string that might be a date and time with either AM or PM specified for the time. This bit of code looks for the optional AM or PM. The error I get is: The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions What would 'distinct sub-expressions' mean in this case? The code: let ampmRef = Reference<Substring>() let ampmReg = Regex { Capture(as: ampmRef) { ZeroOrMore { ChoiceOf { One("am") One("pm") } } } transform: { $0.lowercase } }.ignoresCase() In a related question, is there a way to return a default if the ChoiceOf fails both AM and PM?
3
0
281
May ’24
IBOutlet becomes nil after ViewController is initialized
I have an extremely straightforward situation where an @IBOutlet in a ViewController is connected to a property in an XIB file. I've been working with iOS apps for more than ten years, and done this about a million times. For some reason, the property becomes nil at some point after the view is loaded. I can check with the debugger to see that it is not nil at viewDidLoad, and there is nothing in my code that sets it to anything else. I added a custom setter and getter to the variable so that I could stop in the debugger when it gets set, and the setter only gets called once, with a non-nil value. I suspect that somehow, a different copy of my ViewController is getting instantiated, but when it does, there are no calls to any of the usual methods like viewDidLoad. In fact there is not even a call to the init method. I don't understand how this is possible.
1
0
231
May ’24
Alternative to CoreTelephony for Accessing Cellular Network Information in Private iOS App
Hello, I am developing a private internal Flutter app for our customer, which will not be published on the Apple Store. One of the key features of this app is to collect RF strength metrics to share user experience with the network. For Android, we successfully implemented the required functionality and are able to collect the following metrics: Signal strength level (0-4) Signal strength in dBm RSSI RSRQ Cell ID Location Area Code Carrier name Mobile country code Mobile network code Radio access technology Connection status Duplex mode However, for iOS, we are facing challenges with CoreTelephony, which is not returning the necessary data. We are aware that CoreTelephony is deprecated and are looking for alternatives. We noticed that a lot of the information we need is available via FTMInternal-4. Is there a way to access this data for a private app? Are there any other recommended approaches or frameworks that can be used to gather cellular network information on iOS for an app that won't be distributed via the Apple Store? my swift code import Foundation import CoreTelephony class RfSignalStrengthImpl: RfSignalStrengthApi { func getCellularSignalStrength(completion: @escaping (Result<CellularSignalStrength, Error>) -> Void) { let networkInfo = CTTelephonyNetworkInfo() guard let carrier = networkInfo.serviceSubscriberCellularProviders?.values.first else { completion(.failure(NSError(domain: "com.xxxx.yyyy", code: 0, userInfo: [NSLocalizedDescriptionKey: "Carrier not found"]))) return } let carrierName = carrier.carrierName ?? "Unknown" let mobileCountryCode = carrier.mobileCountryCode ?? "Unknown" let mobileNetworkCode = carrier.mobileNetworkCode ?? "Unknown" let radioAccessTechnology = networkInfo.serviceCurrentRadioAccessTechnology?.values.first ?? "Unknown" var connectionStatus = "Unknown" ... ... } Thank you for your assistance.
4
0
418
May ’24
Accessibility Hint When There are Multiple Actions
Hi there -- I'm cleaning up the accessibility in our app and making sure it adheres to Apple's suggested guidelines. For accessibilityHint, apple lists a couple of suggestions in the doc here: https://developer.apple.com/documentation/objectivec/nsobject/1615093-accessibilityhint Notably this one is one that I'm having to change a lot in our app: Don’t include the action type in the hint. For example, don't create hints like “Tap to play the song” or “Tapping plays the song.” However, we have some buttons that do different actions based on a double or triple tap in VoiceOver, so our hint looks something like: "Double tap to do X, Triple Tap to do Y" This violates the accessibilityHint guidelines, but I feel like changing this would mean the customer loses out on valuable information. What does apple suggest we do in this case? Thanks in advance!
2
0
245
May ’24
Trying to integrate Oracle Digital Assistant into an ios app
Hello fellow developers, We are trying to develop a chatbot application for ios devices using the powers of Oracle Digital Assistant. Main Documentation :- https://docs.oracle.com/en/cloud/paas/digital-assistant/use-chatbot/oracle-ios.html Implementation instructions :- https://blogs.oracle.com/digitalassistant/post/oracle-techexchange-using-the-oracle-ios-sdk-to-integrate-oracle-digital-assistant-in-mobile-applications The point is when we are trying to run the app, we are facing tons of warnings as in below screenshot. Here is the code for the ViewController.swift as below: // // ViewController.swift // ODA_Configure // // Created by Macbook on 15/05/24. // //import UIKit // //class ViewController: UIViewController { // // override func viewDidLoad() { // super.viewDidLoad() // // Do any additional setup after loading the view. // } // // //} // Import the SDK import UIKit import BotClientUISDK public class ViewController: UIViewController { // Declare a global BotsViewController variable in your app view controller class public var chatViewController: BotsViewController? public override func viewDidLoad() { super.viewDidLoad() // Obtain a shared instance of BotsViewController from BotsUIManager chatViewController = BotsUIManager.shared().viewControllerInstance() // Specify the color changes if any in a particular component. Make sure you set all the required colors in BotsProperties before adding the chat view to the view controller. // Add the chatViewController to your navigationController self.navigationController?.pushViewController(chatViewController!, animated: false) // Obtain a shared instance of BotsManager let botsManager = BotsManager.shared() // If you require access to callback methods provided in AuthenticationProvider. Make sure your class conforms to BotsMessageServiceDelegate // botsManager.authenticationTokenProvider = self let baseUrl = "idcs-oda-81e5e7409d52405784089abe830a8820-da12.data.digitalassistant.oci.oraclecloud.com" let channelID = "ff8a2d3f-7d65-4dab-a09a-d8f574ce5b7a" // Initialize a BotsConfiguration object and set feature flags if required. let botsConfiguration = BotsConfiguration(url: baseUrl , channelId: channelID) BotsManager.shared().connect(botsConfiguration: botsConfiguration) // Set the feature flag values if the desired values are different from the default values botsConfiguration.showConnectionStatus = true botsConfiguration.enableSpeechSynthesis = true botsConfiguration.disablePastActions = "none" // Initialize the configuration in botsViewController. Make sure you set all the feature flag values before passing the botsConfiguration to initConfiguration. chatViewController?.initConfiguration(botsConfiguration: botsConfiguration) // If you require access to callback methods provided in BotsMessageServiceDelegate. Make sure your class conforms to BotsMessageServiceDelegate //botsManager.delegate = self // If you require access to callback methods provided in BotsEventListener. Make sure your class conforms to BotsEventListener //botsManager.botsEventListener = self // Initialize and establish connection to the chat server BotsManager.shared().initialize(botsConfiguration: botsConfiguration, completionHandler: { (connectionStatus, error) in if error != nil { print ("Error: \(String(describing: error?.localizedDescription))") } else { print ("Connection Status: \(connectionStatus)") } }) } } After executing this code, we are getting the message as build succeeded , and this is the emulator, which happens to be blank white all the time. Possibly due the warning which I have posted above this seems to be the showstopper in the development. We are developing this for a prestigious client and would request an assistance as soon as possible. P.S :- We are using Xcode 15 with Simulator of version 17.0.
0
0
243
May ’24
Increase in app crashes on iOS 17.4
We have an iOS app built using Capacitor. We are seeing a large increase in app crashes on iOS 17.4 (iPhone). Other OS versions seem to be showing significantly fewer crash numbers. We are unsure what is causing this, as our app did not go through any major releases. I have attached the crash log below. Thanks Exception Type: EXC_CRASH (SIGKILL) Exception Codes: 0x0000000000000000, 0x0000000000000000 Termination Reason: RUNNINGBOARD 0xd00d2bad
5
0
497
May ’24