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.
Post
Replies
Boosts
Views
Activity
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.
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.
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)"
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.
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()