Post

Replies

Boosts

Views

Activity

Returning a type from an Intent (basics)
Hello, I'm attempting to learn the basics of AppIntents. My test Hello World intent takes a number and doubles it. This page (https://developer.apple.com/documentation/appintents/providing-your-app-s-capabilities-to-system-services) seems to imply that you can return types from the perform() function. My code compiles, but crashes at runtime with the error perform() returned types not declared in method signature - Did not declare ReturnsValue but provided one Code: struct DoubleANumber: AppIntent { static var title: LocalizedStringResource = "Double a number" static var description = IntentDescription("Given a number, gives back twice that number.") @Parameter(title: "Start Number") var inputNumber: Double static var parameterSummary: some ParameterSummary { Summary("The number to double") } func perform() async throws -> some IntentResult & ReturnsValue { let outputNumber = inputNumber * 2 return .result(value: outputNumber) } } The value returned in the value property of the IntentResult is a Double. I would have assumed that this would be a valid primitive type (as mentioned in the earlier section of that docs page, covering parameters) and that the actual type returned is the wrapper .result type would be covered in the type in the method signature some IntentResult & ReturnsValue What am I missing? Thanks.
2
0
716
Nov ’23
TextField("x", value: $y, format: .currency(code: "USD")) Behaves oddly
Hello, If we have the following code: import SwiftUI struct ContentView: View { @State private var usdAmount = 0.0 var body: some View { VStack { Text("Currency Form") Form { TextField("Dollar Amount", value: $usdAmount, format: .currency(code: "USD")) // 1 // TextField("Dollar Amount", value: $usdAmount, format: .number) // 2 .keyboardType(.numberPad) } Text("usdAmount = \(usdAmount)") } .padding() } } When the line marked // 1 is left uncommented (the TF has a .currency() formatter applied) the behaviour of the TF is rather odd. Upon display it shows US$0.00 Upon editing the value the US$ part remains. So if the user enters US$123 the value is not stored into the usdAmount property. The User must delete all the existing text and enter e.g. 456.78 and then the value is stored to the usdAmount property. When Line //1 is commented-out and line //2 is uncommented then the TF behaves correctly because the TF value is just 0 on first display. Should we not use the .currency() format? Or am I using it wrong? Thanks.
2
0
457
Jun ’24
Cannot scan for iBeacons (macOS)
Hello, I am attempting a very simple AppKit app on MacOS which displays nearby iBeacons. I don't appear to ever have region scanning available on my system though. Am I doing something wrong? FYI: My system is a MacBook Pro (16-inch, 2019) running Catalina (10.15.7) The target has 'Bluetooth' and 'App Location' enabled in the 'App Sandbox' capabilities section and 'Location' enabled under 'Hardened Runtime'. For a second question: is it possible to scan for any beacons, not just my own (i.e. scan without setting a proximity UUID)? //  ViewController.swift //  Beacons import Cocoa import CoreLocation class ViewController: NSViewController, CLLocationManagerDelegate {     var locationManager: CLLocationManager!     override func viewDidLoad() {         super.viewDidLoad()         locationManager = CLLocationManager()         locationManager.requestAlwaysAuthorization()         locationManager.delegate = self     }     @IBAction func buttonTapped(_ sender: NSButton) {         self.startScanning()     }     override var representedObject: Any? {         didSet {             // Update the view, if already loaded.         }     }     func startScanning() {         print("starting scanning") //UUID Obscured for forum post...         guard let uuid = UUID(uuidString: "xxxxxxxx-E4A1-4720-9034-xxxxxxxxxxxx") else {             print("Couldn't make UUID")             return         }         let beaconID = "com.monkeyfood.myBeaconRegion"         let beaconRegion = CLBeaconRegion(uuid: uuid, identifier: beaconID) //        let beaconRegion = CLBeaconRegion(uuid: UUID(), identifier: beaconID)         self.locationManager.startMonitoring(for: beaconRegion)     }          //. CLLocationManagerDelegate Methods     func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {         var newStatus = ""         switch status {         case .notDetermined:             newStatus = "Not determined"         case .restricted:             newStatus = "Restricted"         case .denied:             newStatus = "Denied"         case .authorizedAlways:             newStatus = "Authorised Always"         case .authorized:             newStatus = "Authorised"         default:             newStatus = "What?"         }         print("LM Auth Status is now: \(newStatus)") // Check for iBeacon monitoring status         let regionMonitoringIsAvailable = CLLocationManager.isMonitoringAvailable(for: CLBeaconRegion.self)         let not = regionMonitoringIsAvailable ? "" : "not "         print("Beacon monitoring is \(not)available")     }     func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {         if beacons.count > 0 { //            updateDistance(beacons[0].proximity)             print("\(beacons.count) beacons found.")             print("\(beacons[0].proximity) dist.")         } else { //            updateDistance(.unknown)         }     }     func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {         print("region entered... \(region)")     }     func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {         print("region exited... \(region)")     }     func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) {         print("determined  region state")     }     func locationManager(_ manager: CLLocationManager, monitoringDidFailFor region: CLRegion?, withError error: Error) {         print("region monitoring failed: \(error)")     }     func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {         print("LM failed \(error)")     } } Always gives me the following: LM Auth Status is now: Authorised Always Beacon monitoring is not available starting scanning region monitoring failed: Error Domain=kCLErrorDomain Code=5 "(null)"
1
0
1.2k
Jul ’21
Catalina - OS needs user's permission for desktop on every rebuild
Please excuse me if this is an obvious question, I tried Googling, but all the results are for instructions for users of released products.I have a small proof-of-concept bit of code that I'm working on which involves traversing the filesystem. I have a test folder on my desktop which the code walks though.Every time I build and run in Xcode I have to grant permission to the app to access the desktop. Is there a way to permanently grant access to my target whilst I'm in development?Thanks.
1
0
407
May ’20
NetServiceBrowser (Bonjour) - why must stop() be called before searches work?
Hello,In the documentation for Foundation's NetServiceBrowser (https://developer.apple.com/documentation/foundation/netservicebrowser) it states:"To use an NSNetServiceBrowser object to search for services, allocate it, initialize it, and assign a delegate. (If you wish, you can also use the schedule(in:forMode:) and remove(from:forMode:) methods to execute searches on a run loop other than the current one.) Once your object is ready, you begin by gathering the list of accessible domains using either the searchForRegistrationDomains() or searchForBrowsableDomains() methods. From the list of returned domains, you can pick one and use the searchForServices(ofType:inDomain:) method to search for services in that domain."However, that's not quite true. There must be a call to the stop() function of the browser before searches work.e.g. if you place the code below into a Swift Playground you get the error:Didn't search for service because: ["NSNetServicesErrorDomain": 10, "NSNetServicesErrorCode": -72003]If you uncomment line 21 then the code works. Why does one have to call stop() on the NetServiceBrowser before searching, and shouldn't the docs mention this?Thanks.import Foundation class DenonFinder: NSObject, NetServiceBrowserDelegate { let browser = NetServiceBrowser() func start() { browser.delegate = self print("Search for registration domains") browser.searchForRegistrationDomains() } //MARK: NetServiceBrowserDelegate func netServiceBrowser(_ browser: NetServiceBrowser, didFindDomain domainString: String, moreComing: Bool) { print("didFindDomain: \(domainString)") if (moreComing) { print("moreComing") } // Why must stop be called before search? // browser.stop() let webService = "_http._tcp." print("searchForServices: \(webService) in domain \(domainString)") browser.searchForServices(ofType: webService, inDomain: domainString) } func netServiceBrowserWillSearch(_ browser: NetServiceBrowser) { print("Search about to begin") } func netService(_ sender: NetService, didNotResolve errorDict: [String : NSNumber]) { print("Resolve error:", sender, errorDict) } func netServiceBrowserDidStopSearch(_ browser: NetServiceBrowser) { print("Search stopped") } func netServiceBrowser(_ browser: NetServiceBrowser, didFind service: NetService, moreComing: Bool) { print("Service found: \(service)") if (moreComing) { print("moreComing") } else { browser.stop() } } func netServiceBrowser(_ browser: NetServiceBrowser, didRemove service: NetService, moreComing: Bool) { print("Service went away: \(service)") } func netServiceBrowser(_ browser: NetServiceBrowser, didNotSearch errorDict: [String : NSNumber]) { print("Didn't search for service because: \(errorDict)") } } class MainApplication { let runLoop = RunLoop.current let distantFuture = Date.distantFuture // let testTimer = Timer.scheduledTimer(withTimeInterval: 4.0, repeats: false, block: {_ in print("timer fired")}) let denonFinder = DenonFinder() /// Set this to false when we want to exit the app... var shouldKeepRunning = true init() { denonFinder.start() } func run() { while shouldKeepRunning == true && runLoop.run(mode:.default, before: distantFuture) {} } } // Entry Point let app = MainApplication() app.run()
3
0
1.8k
Mar ’20