I'm trying to copy some information regarding an accessibility window option. Unfortunately, I can't resolve an error that's caused by the AXUIElementCopyAttributeValue method, despite passing in what appears to be all the correct types as parameters.
Code:
for entry in windowList! as Array {
let ownerName: String = entry.object(forKey: kCGWindowName) as? String ?? "N/A"
let ownerPID: Int = entry.object(forKey: kCGWindowOwnerPID) as? Int ?? 0
let pid = Int32(ownerPID)
//3. Get AXUIElement using PID
let windowAccessibilityElem : AXUIElement = AXUIElementCreateApplication(pid)
print(windowAccessibilityElem)
var position : CFTypeRef? = nil
/****
* This line throws the error
****/
let res : AXError = AXUIElementCopyAttributeValue(windowAccessibilityElem, kAXPositionAttribute as CFString, position as! UnsafeMutablePointer<CFTypeRef?>)
print("res is: \(res)")
...
I'm new to Swift, yet I've read and re-read the documentation on optionals and it really isn't apparent what unexpected value is being passed in- I think it has to do with the position variable, but from what I see I should be passing in the reference correctly. Any help would be apprediated.
You have to assign the pointer to the variable with the in-out operator &
var position : CFTypeRef?
let res : AXError = AXUIElementCopyAttributeValue(windowAccessibilityElem,
kAXPositionAttribute as CFString,
&position)
res contains the error on failure.
position contains the position on success.
In the documentation an in-out parameter is indicated by On return, ...
Related
I was trying to fetch data from firebase to my xcode project. The only fields I have are 'userName', 'age', and 'number'. I was trying to append the values into arrays userNames, ages, and numbers. However, I get the error Error: Cannot convert value of type 'String' to expected argument type 'Int in the appending age and number lines. They both have been entered as Int types in the database.
I thought about converting the values of the database into Int types since I think Xcode is taking them as String types? I tried, but I think my code itself was wrong so I couldn't solve it. I would appreciate the help!
func fetchData () {
let database = Firestore.firestore()
database.collection("users").addSnapshotListener {(snap, Error) in
if Error != nil {
print("Error")
return
}
for i in snap!.documentChanges {
let documentID = i.document.documentID
let userName = i.document.get("userName")
let age = i.document.get("age")
let number = i.document.get("number")
DispatchQueue.main.async {
self.userNames.append("\(userName)")
self.ages.append("\(Int(age))") // error line
self.numbers.append("Int\(number)") // error line
}
}
}
}
You can try to coerce the data into the types you want by using as?. (get returns Any? by default)
let userName = i.document.get("userName") as? String
let age = i.document.get("age") as? Int
let number = i.document.get("number") as? Int
Keep in mind that you'll end up with Optional values, so you'll need to have a fallback in case you don't get the type you expect.
If you wanted to provide defaults, you could do:
let userName = i.document.get("userName") as? String ?? ""
let age = i.document.get("age") as? Int ?? 0
let number = i.document.get("number") as? Int ?? 0
Then, later:
self.userNames.append(userName)
self.ages.append(age)
Note that your compilation errors were happening because you were trying to store String values ("") in an [Int]
In general, rather than storing all of these in separate arrays, you may want to look into making a struct to represent your data and storing a single array with that type. See this answer for an example: https://stackoverflow.com/a/67712824/560942
And, the Firestore documentation on custom objects: https://firebase.google.com/docs/firestore/manage-data/add-data#custom_objects
I am looping trough a snapshot retrieved from a Firestore database getting values into my custom object with conditional unwrapping like the example below. It works fine as long as the key has a value, but as soon as it is empty i get an exception on line if let temp = document.get("windGust") as! String? (See error further down)
I thought conditional unwrapping was supposed to handle this ?
Can anyone point me in the right direction on how to handle this in code? If the value of windGust is empty it should just ignore it and continue.
db.collection("yrData").getDocuments { (snapshot, error) in
for document in snapshot!.documents {
let yrData = YrData()
if let temp = document.get("windGust") as! String?
{
yrData.windGust = temp
}
The error:
Could not cast value of type '_NSZeroData' (0x7fff87d0b5b8) to 'NSString' (0x7fff87d0eee8).
2020-01-16 21:29:23.417663+0100 Victoria[13603:708774] Could not cast value of type '_NSZeroData' (0x7fff87d0b5b8) to 'NSString' (0x7fff87d0eee8).
Maybe not an answer to my question, but this is a solution:
Instead of using:
if let temp = document.get("windGust") as! String?
{
yrData.windGust = temp
}
Use data() like this:
yrData.windGust = data["windGust"] as? String ?? ""
You may just need to use the null coalescing operator.
Something like that would read; if windGust lookup is not a string, assign an empty string.
yrData.windGust = document.get("windGust") as? String ?? ""
I am using firebase to retrieve a list of data then convert it to an NSDictonary array. I want to parse the data by a property e.g name
func getAllMyModels() {
if let e = email {
_ = ref.child("childName").queryOrdered(byChild: "email").queryEqual(toValue: e).observe(.value) { snapshot in
var dictionary = [NSDictionary]()
let children = snapshot.children
while let rest = children.nextObject() as? DataSnapshot, let value = rest.value {
dictionary.append(NSDictionary(dictionary: value as! [String: Any]))
}
let names = dictionary.flatMap {$0["name"]} // names print correct values
let set = Set(names)
print(set)
}
}
}
This code can't be complied the error is:
Showing Recent Messages
Command failed due to signal: Segmentation fault: 11
If i removed this line:
let set = Set(Array(names))
all works fine.
I also tested by replace it by this block
let ar = ["name1","name2"].flatMap { return $0 }
Set(ar)
No errors.
Not sure why? Who can tell, thanks!
EDIT: Even though the element in the array is String type but the names array is [Any], so the solution is
let names = dictionary.flatMap {$0["name"]} as! [String]
I think this errors occurs because the Array you generate from the dictionary with flatMap is an Array of Any and not a String Array, try to cast to a String like this:
...
let names = dictionary.flatMap {$0["name"] as? String}
let set = Set(Array(names))
...
Hope this help you
Cast names to [String]:
let names = dictionary.flatMap {$0["name"]} as! [String]
I'm trying to parse data from a dictionary. I have code that currently works but I think there is a better more concise way to do it.
I have three options for what my dictionary can equal
let dictionary:[String:Any] = ["pic":"picture"] //opt1
let dictionary:[String:Any] = ["pic":2] //opt2
let dictionary:[String:Any] = ["pi":"this"] //opt3
This is the code that I am currently using to parse the data that I would like to be improved.
let _pic = dictionary["pic"]
if _pic != nil && !(_pic is String) {
print("error")
return
}
let pic = _pic as? String
For each option i'd like different things to happen for:
opt1
pic:String? = Optional(picture)
opt2 An error to be shown
opt3
pic:String? = nil
You can try this,
guard let _pic = dictionary["pic"] as? String else { return }
let _pic = dictionary["pic"]
This by default gives you an optional value for _pic that's of type Any?. As such, your code seems OK based on your requirements and I don't think you need the last line let pic = _pic as? String
I think you need to do two tests. Here's one way:
guard let picAsAny = dictionary["pic"]
else { /* No key in the dictionary */ }
guard let pic = picAsAny as? String
else { /* error wrong type */ }
// pic is now a (nonoptional) string
Obviously you can use if statements instead of guards depending on context.
I have this :
let value = data[1] // its a string
print("val:",value) // prints 28.3
let a:Float = Float(value)!
print("a:",a)
Which prints a ok till sometimes crashes where value has a value on it
fatal error: unexpectedly found nil while unwrapping an Optional value
I can put the question mark to mark it as optional, but I am trying to understand how it crashes when there is a value .
Try to use optional wrapping with if let.
if let a = value as? Float {
print("a:%f",a)
}
To remove space try like this
let newValue = value.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
Swift 3
let newValue = value.trimmingCharacters(in: .whitespaces)