Posts

Post marked as solved
1 Replies
312 Views
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.
Posted
by Diggory.
Last updated
.
Post marked as solved
1 Replies
584 Views
Hello, The documentation states that one can add a custom sound to User Notifications. This works on iOS, but doesn't appear to work on macOS. Am I holding it wrong, or are the docs wrong? https://developer.apple.com/documentation/usernotifications/unnotificationsound Example minimal project to demo is here: https://github.com/Diggory/macOSLocalNotifications Thanks.
Posted
by Diggory.
Last updated
.
Post not yet marked as solved
1 Replies
1.1k Views
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)"
Posted
by Diggory.
Last updated
.
Post not yet marked as solved
1 Replies
348 Views
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.
Posted
by Diggory.
Last updated
.
Post marked as solved
3 Replies
1.5k Views
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()
Posted
by Diggory.
Last updated
.