Discuss Swift.

Swift Documentation

Post

Replies

Boosts

Views

Activity

loaded array from plist. call using AppDelegate() returns empty array.
In app delegate I'm trying to load an array with strings from a plist. I print the plist it prints fine... func loadTypesArray() { guard let path = Bundle.main.path(forResource: "Types", ofType: "plist") else {return} let url = URL(fileURLWithPath: path) let data = try! Data(contentsOf: url) guard let plist = try! PropertyListSerialization.propertyList(from: data, options: .mutableContainers, format: nil) as? [String] else {return} print(plist) typesArray = plist // print(typesArray) } But when I try and access it from a different part of the app using let typesArray = AppDelegate().typesArray the array I get is an empty array! any help?
2
0
318
Jun ’24
Files App Share Context with Security scoped resource fails
I'm creating an App that can accepted PDFs from a shared context. I am using iOS, Swift, and UIKit with IOS 17.1+ The logic is: get the context see who is sending in (this is always unknown) see if I can open in place (in case I want to save later) send the URL off to open the (PDF) document and load it into PDFKit's pdfView.document I have no trouble loading PDF docs with the file picker. And everything works as expected for shares from apps like Messages, email, etc... (in which case URLContexts.first.options.openInPlace == False) The problem is with opening (sharing) a PDF that is sent from the Files App. (openInPlace == True) If the PDF is in the App's Document Folder, I need the Security scoped resource, to access the URL from the File's App so that I can copy the PDF's data to the PDFViewer.document. I get Security scoped resource access granted each time I get the File App's context URL. But, when I call fileCoordinator.coordinate and try to access a file outside of the App's document folder using the newUrl, I get an error. FYI - The newUrl (byAccessor) and context url (readingItemAt) paths are always same for the Files App URL share context. I can, however, copy the file to a new location in my apps directory and then open it from there and load in the data. But I really do not want to do that. . . . . . Questions: Am I missing something in my pList or are there other parameters specific to sharing a file from the Files App? I'd appreciate if someone shed some light on this? . . . . . Here are the parts of my code related to this with some print statements... . . . . . SceneDelegate func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) { // nothing to see here, move along guard let urlContext = URLContexts.first else { print("No URLContext found") return } // let's get the URL (it will be a PDF) let url = urlContext.url let openInPlace = urlContext.options.openInPlace let bundleID = urlContext.options.sourceApplication print("Triggered with URL: \(url)") print("Can Open In Place?: \(openInPlace)") print("For Bundle ID: \(bundleID ?? "None")") // get my Root ViewController from window if let rootViewController = self.window?.rootViewController { // currently using just the view if let targetViewController = rootViewController as? ViewController { targetViewController.prepareToLoadSharedPDFDocument(at: url) } // I might use a UINavigationController in the future else if let navigationController = rootViewController as? UINavigationController, let targetViewController = navigationController.viewControllers.first as? ViewController { targetViewController.prepareToLoadSharedPDFDocument(at: url) } } } . . . . ViewController function I broke out the if statement for accessingScope just to make it easier for me the debug and play around with the code in accessingScope == True func loadPDF(fromUrl url: URL) { // If using the File Picker / don't use this // If going through a Share.... we pass the URL and have three outcomes (1, 2a, 2b) // 1. Security scoped resource access NOT needed if from a Share Like Messages or EMail // 2. Security scoped resource access granted/needed from 'Files' App // a. success if in the App's doc directory // b. fail if NOT in the App's doc directory // Set the securty scope variable var accessingScope = false // Log the URLs for debugging print("URL String: \(url.absoluteString)") print("URL Path: \(url.path())") // Check if the URL requires security scoped resource access if url.startAccessingSecurityScopedResource() { accessingScope = true print("Security scoped resource access granted.") } else { print("Security scoped resource access denied or not needed.") } // Stop accessing the scope once everything is compeleted defer { if accessingScope { url.stopAccessingSecurityScopedResource() print("Security scoped resource access stopped.") } } // Make sure the file is still there (it should be in this case) guard FileManager.default.fileExists(atPath: url.path) else { print("File does not exist at URL: \(url)") return } // Let's see if we can open it in place if accessingScope { let fileCoordinator = NSFileCoordinator() var error: NSError? fileCoordinator.coordinate(readingItemAt: url, options: [], error: &error) { (newUrl) in DispatchQueue.main.async { print(url.path()) print(newUrl.path()) if let document = PDFDocument(url: newUrl) { self.pdfView.document = document self.documentFileName = newUrl.deletingPathExtension().lastPathComponent self.fileLoadLocation = newUrl.path() self.updateGUI(pdfLoaded: true) self.setPDFScale(to: self.VM.pdfPageScale, asNewPDF: true) } else { print("Could not load PDF directly from url: \(newUrl)") } } } if let error = error { PRINT("File coordination error: \(error)") } } else { DispatchQueue.main.async { if let document = PDFDocument(url: url) { self.pdfView.document = document self.documentFileName = url.deletingPathExtension().lastPathComponent self.fileLoadLocation = url.path() self.updateGUI(pdfLoaded: true) self.setPDFScale(to: self.VM.pdfPageScale, asNewPDF: true) } else { PRINT("Could not load PDF from url: \(url)") } } } } . . . . Other relevant pList settings I've added are: Supports opening documents in place - YES Document types - PDFs (com.adobe.pdf) UIDocumentBrowserRecentDocumentContentTypes - com.adobe.pdf Application supports iTunes file sharing - YES And iCloud is one for Entitlements with iCloud Container Identifiers Ubiquity Container Identifiers . . . . Thank you in advance!. B
1
0
314
Jun ’24
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
271
May ’24
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
238
May ’24
XPC, Swift, ObjC, and arrays
I create a protocol that had, among other things: @objc func setList(_: [MyType], withReply: @escaping (Error?) -> Void) The daemon part is in Swift, while the calling part is in Objective-C. Because why not? (Actually, because the calling part has to deal with C++ code, so that's ObjC++; however, I wanted the stronger typing and runtime checking for the daemon part, so I wrote it in Swift.) The ObjC part uses NSArray<MyType*>. I set up an NSXPCConnection link, and create a (synchronous) proxy with the right protocol name. But when I try to do the XPC setList call, I get an error. I assume that's because it doesn't like the signature. (Surely this is logged somewhere? I couldn't find it, if so. 😩) But... if I have a signature of @objc func addItem(_: MyType, withReply: @escaping (Error?) -> Void), then it works. So I assume it's the array. (Oh, I've also tried it without the @objc; the protocol itself is defined as @objc.) I've tried changing to protocol signature to using NSArray, but same thing.
7
0
1.1k
Dec ’21
Xcode 13 typing is delayed / really slow
I just updated Xcode to the newest Version (13.0 13A233). And what I immediately recognized was that when I was typing in a large class (1000 Lines or more) the typing was delayed like 1 or 2 seconds. This makes it really hard to type or even do anything with my project. It works perfectly fine in smaller projects with only 100 Code Lines per File, but it is really hard to type in bigger projects with over 30 files and 3000 Code Lines per File. This always happens when I use Xcode, whether I run the app on a real device or a simulator. Things that could cause the issue in my case: I removed the contents of ~/Library/Developer/Xcode/iOS DeviceSupport, because it took the device previously too long to launch, but I don´t think that this should have an effect on my Xcode typing performance. I would really appreciate any help, because this issue makes my work impossible and really concerns me a lot.
52
3
19k
Oct ’21
How to open Passcode field in Swift XCTest UI with iOS 17.4
This code works when I run it in the iOS Simulator with iOS 17.0.1: let passcodeInput = springboard.secureTextFields["Passcode field"] _ = passcodeInput.waitForExistence(timeout: 10) passcodeInput.tap() However if I run it on the iOS Simulator with iOS 17.4 I get this error: t = nans Checking existence of `"Passcode field" SecureTextField` t = nans Capturing debug information t = nans Requesting snapshot of accessibility hierarchy for app with pid 66943 t = nans Tap "Passcode field" SecureTextField t = nans Wait for com.apple.springboard to idle t = nans Find the "Passcode field" SecureTextField t = nans Find the "Passcode field" SecureTextField (retry 1) t = nans Find the "Passcode field" SecureTextField (retry 2) t = nans Requesting snapshot of accessibility hierarchy for app with pid 66943 <unknown>:0: error: PRCheckUITests : Failed to tap "Passcode field" SecureTextField: No matches found for Descendants matching type SecureTextField from input {( Application, pid: 66943, label: ' ' )} Did the hardcoded string "Passcode field" change for iOS 17.4? How can I access the passcode field through springboard in a test?
1
0
366
Apr ’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
428
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
341
May ’24
Get user's own contact card with unifiedMeContactWithKeys(toFetch:)
Hi everyone! It came to my knowledge from the documentation (https://developer.apple.com/documentation/contacts/cncontactstore/unifiedmecontactwithkeys%28tofetch:%29) that the method unifiedMeContactWithKeys(toFetch:), which fetches the me-card in the phone book by using CNContactStore, was recently made available for iOS as well. The problem is that I regardless get the error saying the method is unavailable for iOS, even though the documentation clearly states it should be available. I have tried several Xcode version including the latest one but to no avail... Does anyone have any idea what is wrong here? Kindest regards, Andreas
1
0
392
Mar ’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
321
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
569
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
233
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
214
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
258
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
479
May ’24
Does setAlternateIconName work in mac Catalyst?
I'm trying to change app icon on Dock in macOS from my app. But couldn't get to work. The setAlternateIconName works fine in iOS simulator, but when I run in on my mac (Catalyst) I got this error: The requested operation couldn’t be completed because the feature is not supported. Apple Doc - https://developer.apple.com/documentation/uikit/uiapplication/2806818-setalternateiconname Thank you
1
1
820
Dec ’22