Formatting NSArray for Swift - ios

I have trouble formatting the NSArray
let temp = json.value(forKeyPath: "data.current_condition.temp_F") as Any
DispatchQueue.main.async {
self.setWeather(temp: temp as! NSArray )
}
func setWeather( temp: NSArray) {
TempLabel.text = "\(temp)"
When I run the program TempLabel only shows " ( " because it's in NSArray form. I am not sure how do I get rid of "(".

Using the description of the object to show it on the UI is quite fragile, and could change anytime internally in iOS.
What I would try instead is to cast the result of your json value into Swift types. In your case [Int] should work. Then use one of the collection methods to convert the Int array to String.
Try something like this:
let temp = json.value(forKeyPath: "data.current_condition.temp_F") as! [Int]
TempLabel.text = temp.map({ "\($0)" }).joined(separator: ", ")

Related

FMDB / sqlite query problem with function

I am really new to swift and trying to understand ios programming. Basically I have a table where "id" and "fact" columns. id is primary key'd and here is the swift fuction I am trying to query the values
func getItemsFromRow(fact_cid: String) ->[FactsData]{
var rowData: [FactsData]!
let rawQ = "select * from facts where \(facts_id)=?"
if (openDatabase()){
do{
let results = try database.executeQuery(rawQ, value(forKey: fact_cid))
while results.next(){
let currentFact = FactsData(factid: results.string(forColumn: facts_id), factsdata: results.string(forColumn: facts_fld))
if rowData == nil {
rowData = [FactsData]()
}
rowData.append(currentFact)
}
}
}
return rowData
}
But this line gives me error
let results = try database.executeQuery(rawQ, value(forKey: fact_cid))
Error is
Cannot invoke 'executeQuery' with an argument list of type '(String, Any?)'
I am trying to pass the id as string. Not sure what I am doing wrong here.
Any help is much appreciated.
Change it to
let results = try database.executeQuery(rawQ, values: [fact_cid])
since the second parameter should be an array

How to filter String array in Swift

By using objective C I have filter year array by using NSPredicate,
Below is code.
yearArray = [yearArray filteredArrayUsingPredicate:[NSPredicate
predicateWithFormat:#"SELF != ''"]];
As per above code it's working fine in objective c , I have to filter array in Swift 3,
What is Input Year Array :-
( Year,"","","",JAN,"","","",FEB,"","","",MAR,"","","",APR,"","","",
MAY,"","","",JUN,"","","",JUL,"","","",AUG,"","","",SEP,"","","",OCT
,"","","", NOV,"","","",DEC,"","","","",WIN,"","","",SPR,"","","",SUM
,"","","",AUT,"","","","",ANN)
Need filter Output Array
(Year,JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC,WIN,SPR,SUM,AUT,ANN)
Please give solution how to filter array in swift.
Use this code:
let yearArray: [String] = ... // your array of type [String]
let filteredArray = yearArray.filter {
!$0.isEmpty
}
Look at the picture for output:
You can do it by using filter (on an Array type) :
let filteredArray = yearArray.filter{$0 != ""}
It's that simple.
If your array is an NSMutableArray, just cast it to [String] :
if let yearArray = yearArray as? [String] {
let filteredArray = yearArray.filter{$0 != ""}
// add your code here
}

(SKNode) not convertible to string (it was working with old xCode)

In my apps I was using this piece of code and it worked perfectly:
var data3: NSArray = [] //1
for gg in data3{ //2
var hh:String = gg["percentage"] as String //3
perchomerec = hh.toInt()! //4
}
Now I updated my xCode and OSx version and now this same piece of code gives this error (on line //3):
[SKNode] is not convertible to String
What do I have to change?
Since Swift 1.2 as operator can only be used for upcasting. When downcasting, you should use as! or as? (detailed description can be found e.g. in The Swift Programming Language).
var hh:String = gg["percentage"] as! String
data3 seem to be of type [[String:Int]] based on your responses on my comments.
So by changing NSArray to [[String:Int]] or just simply removing NSArray completely and letting Swift determine the type by itself.
I guess your question is in pseudo-code so my guess is how you set that data3's data:
let data3 = [["percentage" : 33]] // Swift will determine this type to: [[String:Int]]
for gg in data3 { // gg will become [String:Int]
perchomerec = gg
}
Or if you still want the NSArray type then to cast gg in a for loop you have to cast the array itself:
for gg in data3 as! [[String:Int]]
Edit
If the array changes then it has to be an NSArray or [AnyObject] and then you have to test to cast for every possible type.
for gg in data3 {
if let dict = gg as? NSDictionary {
if let str = dict["percentage"] as? String, nr = str.toInt() {
perchomerec = nr
}
else if let nr = dict["percentage"] as? Int {
perchomerec = nr
}
}
}
It sounds like you need to use ! or ?, although from Jakub Vano's answer it sounds like using optional unwrapping would be more suitable for your code. If you don't expect hh to not be a String or not be nil then I also suggest you check your code elsewhere.
var data3: NSArray = []
for gg in data3 {
if let h = hh as? String {
perchomerec = h.toInt()!
}
}

Swift filter array of strings

I've had troubles filtering array of keywords (strings) in swift ,My code:
self.filteredKeywords=filter(keywords.allValues, {(keyword:NSString) ->
Bool in
let words=keyword as? NSString
return words?.containsString(searchText)
})
As AnyObject can't be subtype of NSString, I'm stuck with this!
[Updated for Swift 2.0]
As NSString is toll-free bridged to Swift String, just avoid the coercions with:
3> ["abc", "bcd", "xyz"].filter() { nil != $0.rangeOfString("bc") }
$R1: [String] = 2 values {
[0] = "abc"
[1] = "bcd"
}
But, if you think allValues aren't strings:
(keywords.allValues as? [String]).filter() { nil != $0.rangeOfString("bc") }
which returns an optional array.
Your filter is over [AnyObject], but your closure takes NSString. These need to match. Also, your result needs to be a Bool, not a Bool?. You can address these simply like this:
self.filteredKeywords = filter(keywords.allValues, {
let keyword = $0 as? NSString
return keyword?.containsString(searchText) ?? false
})
This accepts AnyObject and then tries to coerce it down to NSString. It then nil-coalleces (??) the result to make sure it always is a Bool.
I'd recommend, though, treating keywords as a [String:String] rather than an NSDictionary. That would get rid of all the complications of AnyObject. Then you can just do this:
self.filteredKeywords = keywords.values.filter { $0.rangeOfString(searchText) != nil }
Whenever possible, convert Foundation collections into Swift collections as soon as you can and store those. If you have incoming Foundation objects, you can generally convert them easily with techniques like:
let dict = nsdict as? [String:String] ?? [:]
Or you can do the following to convert them such that they'll crash in debug (but silently "work" in release):
func failWith<T>(msg: String, value: T) -> T {
assertionFailure(msg)
return value
}
let dict = nsdict as? [String:String] ?? failWith("Couldn't convert \(d)", [:])
Swift 4.2 provides a new way to do this:
var theBigLebowski = ["The Dude", "Angry Walter", "Maude Lebowski", "Donny Kerabatsos", "The Big Lebowski", "Little Larry Sellers"]
// after removeAll -> ["The Dude", "Angry Walter", "Donny Kerabatsos", "Little Larry Sellers"]
theBigLebowski.removeAll{ $0.contains("Lebowski")}
print(theBigLebowski)
There is both a problem with GoZoner's answer for certain data types and also a slightly better way to do this. The following examples can show this:
let animalArray: NSMutableArray = ["Dog","Cat","Otter","Deer","Rabbit"]
let filteredAnimals = animalArray.filter { $0.rangeOfString("er") != nil }
print("filteredAnimals:", filteredAnimals)
filteredAnimals: [Dog, Cat, Otter, Deer, Rabbit]
Likely not the set you expected!
However this works fine this way if we don't type animalArray as an NSMutableArray:
let animalArray = ["Dog","Cat","Otter","Deer","Rabbit"]
let filteredAnimals = animalArray.filter { $0.rangeOfString("er") != nil }
print("filteredAnimals:", filteredAnimals)
filteredAnimals: [Otter, Deer]
However I'd recommend using $0.contains() instead of $0.rangeOfString() != nil because it functions in both circumstances and slightly enhances the readability of the code:
let animalArray: NSMutableArray = ["Dog","Cat","Otter","Deer","Rabbit"]
let filteredAnimals = animalArray.filter { $0.contains("er") }
print("filteredAnimals:", filteredAnimals)
filteredAnimals: [Otter, Deer]

Like objective-C , how to write "valueForKey" in swift?

NSDictionary dic;
NSMutableArray array;
//Objective-C Code.
array = [dic valueForKey:#"Table"]; //"Table" is key in dictionary
How to write same code in Swift?
There is no more valueForKey: in Swift, but there is a way to use map to achieve a similar, if not same, result.
If the objects in the collection are dictionaries:
let array = dic.map { $0["table"] as? String }
If the objects in the collection are objects:
let array = dic.map{ $0.table }
If you are using Objective-C collection types like NSDictionary in your example, then like others have said, you can still continue to use valueForKey:.
let array = dic.valueForKey("table")
You can try this
let array: AnyObject? = dic["Table"]
Simple eg.
(dicDetail.valueForKey("name") as! String)
You can try this
var dict=NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: NSErrorPointer.null()) as NSDictionary
var temp=dict["contactname"] as String
var tem=dict.valueForKey("contactname") as String
You will better get the idea of how you can deal with Dictionaries in Swift
let employees = json["employees"]! as [[String : AnyObject]]
Next step is to loop the employees array and print the firstName and lastName.
Keep in mind that we are looping an array of dictionaries. Meaning that in order to get the String values from firstName and lastName we need to unwrap the optionals first:
for employee in employees {
let firstName = employee["firstName"]! as String
let lastName = employee["lastName"]! as String
println("employee: \(firstName) \(lastName)")
}
Build, run and you should see:
employee: John Doe
employee: Anna Smith
employee: Peter Jones
Please check this code. It might help in what you need.
var dictData = Dictionary <String,Any>()
var arrDictData = Array<Any>()
// Will store value for key in dictionary.
func storeData ( strName: String , strAge: String ) {
dictData["name"]=strName
dictData["age"]=strAge
println("dictData: \(dictData)")
storeInArray(dictData)
}
// Will store value of dictionary in array.
func storeInArray ( dict : Any ) {
arrDictData.append(dict)
println("arrDictData: \(arrDictData)")
}
// Will return count of array.
func resultArray() -> Int {
println(arrDictData.count)
return arrDictData.count
}
// This function will return value in label.
func arrDictResult( dictKey: String, rowIndex: Int) -> String {
var dataTemp = arrDictData[rowIndex] as Dictionary <String,Any>
var val = dataTemp[dictKey] as String
return val
}

Resources