I prepare a swift Array in my Watch Interface and send it to the iOS App:
#IBAction func buttonGeklickt() {
if WCSession.isSupported() {
let session = WCSession.defaultSession()
session.delegate = self
session.activateSession()
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "hh:mm"
let datumString = dateFormatter.stringFromDate(NSDate())
var swiftArray = [String]()
swiftArray.append(datumString)
var swiftDict = ["a":swiftArray]
session.transferUserInfo(swiftDict)
}
so far so good, on the iOS App the dictionary arrives, but there seems to be something wrong with the Array in the Dictionary:
func session(session: WCSession, didReceiveUserInfo userInfo: [String : AnyObject]) {
print ("seems to be the same Dict = \(userInfo)")
if let vw = userInfo["a"] as? [String: String] {
print ("Never called! Here I would expect my array from the watch \(vw)")
}
}
I would expect and like vw to hold the same array as swiftArray in the watchApp. However it seems to be of type __NSCFArray:
screenshot
So what I'm doing wrong here?
I'm new to Swift, however I'm experienced with Objective C to solve actually every problem I faced in the past years, but this issue seems to be so basic and it's embarrassing that I'm not able to solve it on my own. So help is much appreciated
If I understand your code correctly, you are saving "a" as value of type [String]. But you are trying to read it as [String:String]. Instead of
if let vw = userInfo["a"] as? [String: String]
try
if let vw = userInfo["a"] as? [String]
Related
I'm using firebase to store the amount of views every video in my app has been seen. What I want to is to gather all views from from one users all videos and display the total number of views. However I'm having problems fetching down the data and putting all the dictionary values together into a Int/String!
Ive tried many different solutions so far, but still I get all the different values in like array / values of the dictionary instead of everything added into one value
This is my code for getting all the videoviews of a specific user, no problems with this so far. When I print "intConvert" I get like all the views in different rows.
let ref = Database.database().reference().child("videoviews").child(stringUid)
ref.observe(.value, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject]{
let numbOfViews = dictionary["views"] as! String
let intConvert = Int(numbOfViews)!
let ArrayViews = [intConvert]
This is my database structure:
**videoviews**
-Lb52VxrEqdSRGljJdP7
views: "25"
-Lb53ARq_lOHEbTruW8s
views: "273"
-Lb53A_cEyX3CYc4mKYn
views: "38"
EDIT: If I do print(dictionary), the dictionary from "if let dictionary = snapshot.value as? [String: Anyobject] looks like this:
["views": 642]
["views": 660]
["views": 628]
["views": 630]
["views": 615]
["views": 3]
["views": 0]
["views": 2]
["views": 1]
Edit: (I was confused and forgot to add the bracelets, sorry for that.)
when I do I "print(dictionary.values) the console looks like this (the key values from different dictionaries):
[642]
[660]
[628]
[630]
[615]
[3]
[0]
[2]
[1]
I then tried to put this together in a loop like this:
var bLoader = 0.0
for hejArray in 0...ArreyViews.count-1{
bLoader += Double(Arrej[hejArray])
}
But when I print "bLoader" I still get all the views for every video in different rows instead of gathered in one value.
So what do I need to do put together all the values from different dictionaries in Firebase into one Variable?
I appreciate all help I can get with this, I can imagine it shouldn't be too hard but that im missing out on something.
EDIT /// I finally found the problem. the "StringUid" that I passed in have different amount of values and therefore the whole function would be called for 9 times if the videos of the user had the amount of 9. The solution that finally worked looked like this:
Global Array declaration:
var myArray = [String]()
Inside the function:
if let dictionary = snapshot.value as? [String: AnyObject]{
let numbOfViews = dictionary["views"] as! String
let intConvert = Int(numbOfViews)!
self.myArray.append(numbOfViews)
let intArray = self.myArray.map { Int($0)!}
let total = intArray.reduce(0, +)
self.totalViewsShower2.text = String(total)
Thank you in advance!
Update
If you can directly print the values from your dictionary like that then the solution might be as easy as
let total = dictionary.values.reduce(0, +)
or if values are strings you need to convert them to Int
let total = dictionary.values.reduce(0) {sum, value -> Int in return sum + (Int(value) ?? 0)}
If on the other hand they values are string but defined as Any you need an extra cast
let total2 = dictionary2.values.reduce(0) {sum, value -> Int in
if let str = value as? String {
return sum + (Int(str) ?? 0)
}
return 0
}
I am not exactly sure what your dictionary contains but I assumed something like this
let dictionary: [String: Any] = ["views": ["1", "2", "3"]]
Then you can cast the value for the "views" key to a String array and then use reduce on that array to get the sum
let array = dictionary["views"] as! [String]
let total = array.reduce(0) {sum, value -> Int in return sum + (Int(value) ?? 0)}
According to your Database structure which looks something like this
{
"videoviews": {
"Lb52VxrEqdSRGljJdP7": {
"views": "25"
},
"Lb53ARq_lOHEbTruW8s": {
"views": "273"
},
"Lb53A_cEyX3CYc4mKYn": {
"views": "38"
}
}
}
let ref = Database.database().reference().child("videoviews").child(stringUid)
ref.observe(.value, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
let viewsArray = dictionary.values
.compactMap { $0 as? [String: String] }
.compactMap { Int($0["views"] ?? "") }
let totalViews = viewsArray.reduce(0, +)
}
})
I'm trying to cast a dictionary of [String:Bool] to an array of string.
my code is:
var action = [Nourishing:true, Radiance:true]
let actionArray = [action.keys.description] as? [String]
but the result comes out as:
["[\"Nourishing\", \"Radiance\"]"]
How do I fix this?
You should use this directly
let actionArray = Array(action.keys)
I'm new to Swift 3 and I have this array of dictionaries in Swift 3:
var arrayPOIsLoaded = [Dictionary<String, Any>]()
And I want to sort it by the Key "name" of the dictionary.
I have look here but nothing seem to work.
I have tried to use predicates but whit no success.
Any help will be appreciated.
Thanks in advance.
Thanks to all.
This is the correct way of writing it:
self.arrayPOIsLoaded.sorted { ($0["name"] as! String) < ($1["name"] as! String) }
You have to add ()
Regards.
Try this
var arrayPOIsLoaded = [Dictionary<String, String>]()
let sortedArray = arrayPOIsLoaded.sorted {$0["name"]! as? String < $1["name"]! as? String}
When I try to run the code below on my iPhone, I get the following error
rrr.swift:356:72: Ambiguous use of 'subscript'
The strange thing is it happens only when I want to run the app on the phone, on the simulator however it works fine.
There are 3 lines which cause the error where. I noted them below in the code in capital letters.
I try to access properties in an array inside the JSON array, I suspect Im doing it the wrong way but have no idea how to fix it.
How can these properties be retrieved without the subscript error?
self.restApi.getSchoolDetails(schoolId) {responseObject, error in
// use responseObject and error here
self.schoolDetailsCollection = NSDictionary(dictionary: responseObject! as! [String : AnyObject])
print(self.schoolDetailsCollection)
if let response = responseObject as? NSDictionary {
//parse the response object
self.schoolDetailsList = (response as? NSDictionary)!
//assigning all values to shareData class
self.shareData.sco_id = response["result"]!["sco_id"] as!NSInteger
self.shareData.address = response["result"]!["address"] as!String
self.shareData.name = response["result"]!["name"] as! String
print("school name")
print(self.shareData.name)
self.shareData.intro = response["result"]!["intro"] as! String
self.shareData.sell_point = response["result"]!["sell_point"] as! String
self.shareData.city = response["result"]!["city"] as! String
self.shareData.cou_id = response["result"]!["cou_id"] as! String
//get images from the nested array in the json array
/THESE THREE LINES CAUSE THE ERROR SUBSRCIPT
self.shareData.image1 = response["result"]!["images"][0]! as! String
self.shareData.image2 = response["result"]!["images"]![1] as! String
self.shareData.image3 = response["result"]!["images"]![2] as! String
print(self.shareData.image1)
print(self.shareData.image2)
print(self.shareData.image3)
//open next controller after all info has been set correctly
//info is being passed by Singleton class Sharedata
if let COBezierDemoViewController = self.storyboard!.instantiateViewControllerWithIdentifier("COBezierDemoViewController") as? COBezierDemoViewController {
self.presentViewController(COBezierDemoViewController, animated: true, completion: nil)
}
}
}
}
The JSON file:
{
result = {
address = "223 Vincent St, West Perth WA 6005, Australia";
city = Perth;
"cou_id" = AU;
"cur_id" = "";
environment = R;
financed = "<null>";
images = (
"Phoenix_Academy_1.jpeg",
"Phoenix_Academy_3.jpeg",
"Phoenix_Academy_2.jpeg"
);
intro = "Our language school in Perth has a modern campus and a spacious garden. The language school is located 10 minutes north from the city center. You can reach the city center and the famous bea
As you hint that error in this line:
self.shareData.image1 = response["result"]!["images"][0]! as! String
Error:
Error is [0] subscript which you are implementing in AnyObject.
response["result"]!["images"] // this is returning Optional<AnyObject> which do not have subscript option.
Correct way should be this:
Downcast AnyObject as? [String] // this will either return nil or an Optional Array<String?> where String is image name.
Without downcasting, you will get error: Ambiguous use of subscript.
let images = response["result"]? ["images"] as? [String]
images?.flatMap({ $0 }).forEach {
print($0) // Phoenix_Academy_1.jpeg, Phoenix_Academy_3.jpeg, Phoenix_Academy_2.jpeg
}
I keep getting an error of "ambiguous use of subscript," in my Swift code. I don't know what's causing this error. It just randomly popped up. Here's my code:
if let path = NSBundle.mainBundle().pathForResource("MusicQuestions", ofType: "plist") {
myQuestionsArray = NSArray(contentsOfFile: path)
}
var count:Int = 1
let currentQuestionDict = myQuestionsArray!.objectAtIndex(count)
if let button1Title = currentQuestionDict["choice1"] as? String {
button1.setTitle("\(button1Title)", forState: UIControlState.Normal)
}
if let button2Title = currentQuestionDict["choice2"] as? String {
button2.setTitle("\(button2Title)", forState: UIControlState.Normal)
}
if let button3Title = currentQuestionDict["choice3"] as? String {
button3.setTitle("\(button3Title)", forState: UIControlState.Normal)
}
if let button4Title = currentQuestionDict["choice4"] as? String {
button4.setTitle("\(button4Title)", forState: UIControlState.Normal)
}
if let question = currentQuestionDict["question"] as? String!{
questionLabel.text = "\(question)"
}
The problem is that you are using NSArray:
myQuestionsArray = NSArray(contentsOfFile: path)
This means that myQuestionArray is an NSArray. But an NSArray has no type information about its elements. Thus, when you get to this line:
let currentQuestionDict = myQuestionsArray!.objectAtIndex(count)
...Swift has no type information, and has to make currentQuestionDict an AnyObject. But you can't subscript an AnyObject, so expressions like currentQuestionDict["choice1"] cannot compile.
The solution is to use Swift types. If you know what currentQuestionDict really is, type it as that type. At the very least, since you seem to believe it is a dictionary, make it one; type it as [NSObject:AnyObject] (and more specific if possible). You can do this in several ways; one way is by casting when you create the variable:
let currentQuestionDict =
myQuestionsArray!.objectAtIndex(count) as! [NSObject:AnyObject]
In short, never use NSArray and NSDictionary if you can avoid it (and you can usually avoid it). If you receive one from Objective-C, type it as what it really is, so that Swift can work with it.
["Key"] has causing this error. New Swift update, you should use objectForKey to get your value. In you case just change the your code to ;
if let button1Title = currentQuestionDict.objectForKey("choice1") as? String {
button1.setTitle("\(button1Title)", forState: UIControlState.Normal)
}
This is the code I used to solve the error:
let cell:AddFriendTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! AddFriendTableViewCell
let itemSelection = items[indexPath.section] as! [AnyObject] //'items' is an array of NSMutableArrays, one array for each section
cell.label.text = itemSelection[indexPath.row] as? String
Hope this helps!