Issues adding NSIndexPath as key and NSNumber as value in Dictionary? - swift

Second object of quickFilterDictionary in self.preferencesListFilterDictionary is nil. How to add [NSIndexPath] index path (as key) and NSNumber (as value) in Dictionary?
Note: first object is added successfully, only the 2nd object is nil when I printed self.preferencesListFilterDictionary in console. May I know , what am I doing wrong in below code?
self.preferencesListFilterDictionary["price"] = 1000
self.quickFilterArr = [localizedStrOf("deliveryNowOnly"),localizedStrOf("rated")]
var quickFilterDictionary = Dictionary<NSIndexPath, NSNumber?>()
for obj in self.quickFilterArr {
let row = self.quickFilterArr.indexOf(obj)
let indexPath = NSIndexPath(forRow:row!, inSection: 0)
quickFilterDictionary[indexPath] = NSNumber(bool: false)
}
print(quickFilterArr.count)
print(quickFilterDictionary)
self.preferencesListFilterDictionary.updateValue(quickFilterDictionary as? AnyObject, forKey: "quickFilterDictionaryKey")
print(self.preferencesListFilterDictionary)
console print:
▿ [1] : 2 elements
- .0 : "quickFilterDictionaryKey"
- .1 : nil
To get above dictionary bool from number, I wrote following code -
func getQuickFilterValueOfIndexpath(indexPath:NSIndexPath) -> Bool {
if let val = self.preferencesListFilterDictionary["quickFilterDictionaryKey"] {
// now val is not nil and the Optional has been unwrapped, so use it
let tempDict = val as! Dictionary<NSIndexPath, NSNumber?>
if let boolVal = tempDict[indexPath] {
return boolVal!
}
}
return false
}

I think you are confused on the difference between a Row, an IndexPath, and an Index.
In the following code:
let row = self.quickFilterArr.indexOf(obj)
If you option click on row, you will see that it is an object of type Array.Index?. It is not an row.
Also is there a reason you are using NSNumber, NSIndexPath and update value for key? As opposed to Number, IndexPath and just updating your dictionary values with:
preferencesListFilterDictionary["quickFilterDictionaryKey] = quickFilterDictionary
If you option click on quickFilterArr and it is an array of IndexPaths [IndexPath] - To reference the IndexPath at your chosen index in that array you would just do:
if let arrayIndex = quickFilterArr.indexOf(obj) {
//if your array is an array of Index Paths
//you would then pull the IndexPath object at the index you have defined above
let indexPath = quickFilterArr[arrayIndex]
quickFilterDictionary[indexPath] = Number(bool: false)
}

Related

Could not cast value of type in get notification userInfo

Why does an error appear here?
if let tskNum = notification.userInfo!["NUM"] {
let indexPath = IndexPath(row: tskNum as! Int, section: 0)
}
Error: Could not cast value of type 'Swift.String'
The value type of userInfo is Any, you have to downcast Any to String first and then convert String to Int.
if let tskNum = notification.userInfo?["NUM"] as? String,
let row = Int(tskNum) {
let indexPath = IndexPath(row: row, section: 0)
}
If you are responsible for the userInfo dictionary why do you pass a String value?
Casting is incorrect, you can't get an integer value from a string(auto typecasting is not possible). Please update -
if let tskNum = notification.userInfo!["NUM"], let index = Int(tskNum) {
let indexPath = IndexPath(row: index, section: 0)
}

is any function to modify the json parse dictionary array

i have dictionary array in witch i have to modify the array object isRead
let dict = arr[indexPath]
var Added = dict["IsRead"] as! NSNumber
if Added == 0
{
Added = 1
}
Why NSNumber? The name isRead implies that the type is Bool.
Due to value semantics you have to modify arr
let dict = arr[indexPath.row]
if let isRead = dict["IsRead"] as? Bool, isRead == false {
arr[indexPath.row]["IsRead"] = true
}

Cannot convert value of type Int to expected argument type IndexPath (Core Data)?

I have the following code where I get fetchedObjects from a Core Data stack. How can I access the elements of these? It throws an error saying I need an IndexPath?
func loadDataToMapView() {
guard let mapCoordinates = fetchedResultsControllerForCoordinateEntity.fetchedObjects else { return 0 }
let coordinate2 = fetchedResultsControllerForCoordinateEntity.object(at: 1)
print(coordinate2)
NSFetchedResultsController.object method required an IndexPath. An IndexPath is composed by section and row. If you have only one section you can try with this
let myIndexPath = IndexPath(row: 1, section: 0)
let coordinate2 = fetchedResultsControllerForCoordinateEntity.object(at: myIndexPath)

Retrieve a Childs Child in Firebase - Unwrap unique-post-ids

I am trying to unwrap data in childs from childs basically. My current database structure looks like this:
- user-posts
- <user-id>
- user-data
- <unique-post-id> (As a result from childByAutoId)
- the data I want to display
- <unique-post-id> (As a result from childByAutoId)
- the data I want to display
...
-<user-id>
-...
-<user-id>
...
So as it can be seen, the actual data I want to retrieve is always a child of <unique-post-id>, which is automatically generated when the data is written to the database. Retrieving from the database I so far only get:
- <unique-post-id>
- <unique-post-id>
- ...
Is there a way of unwrapping those and display their childs? What is working for me now is displaying all the unique post id's, but I can't figure out how to get then the child below them, and that for all of them.
The code I'm using to retrieve the data:
func getQuery() -> FIRDatabaseQuery {
let myTopPostsQuery = (ref.child("user-posts")).child(getUid()).child("user-data")
return myTopPostsQuery
}
dataSource = FirebaseTableViewDataSource.init(query: getQuery(),cellReuseIdentifier: "Cellident", view: self.tableView)
dataSource?.populateCellWithBlock { (cell: UITableViewCell, obj: NSObject) -> Void in
let snap = obj as! FIRDataSnapshot
cell.textLabel?.text = snap.key as String
}
dataSource?.populateCellWithBlock { (cell: UITableViewCell, obj: NSObject) -> Void in
let snap = obj as! FIRDataSnapshot
cell.textLabel?.text = snap.key as! String
let childString = snap.value as! String
// If the child is another dictionary use `as! [String : AnyObject]`
}
But a different approach might go like this : -
ref.child("user-posts")).child(getUid()).child("user-data").observeEventType(.Value, withBlock: { (snap) in
if snap.exists(){
for each in snap as! [String : AnyObject] {
let childString = snap.Value as! String
}
}
})

Populating a global dictionary from a loop

I'm trying to loop through some parsed JSON from an API and build a global dictionary that can be accessed throughout the app. I'm getting an error when trying to set the dictionary item.
The global var is set as
var propListArray = [Int : [String : String]] ()
//LOOP THROUGH PROPERTIES
let itemArray = dataDictionary["properties"] as! NSArray //HAVE DATA HERE JUST FINE
var i = 0
for item in itemArray {
let propertyID = item["id"]! as! String
print(propertyID) //THIS PRINTS FINE IN CONSOLE
propListArray[i]!["propertyID"] = propertyID //THIS THROWS AN ERROR ON EXECUTION
i++
}
I want to end up with an array like this
propertyListArray[0]["propertyID"] = "16001"
propertyListArray[1]["propertyID"] = "16001"
propertyListArray[2]["propertyID"] = "16001"
propertyListArray[3]["propertyID"] = "16001"
There will be other vars per item as well such as title, etc. But just trying to get at least the one var in on each item.
Any help would be amazing!! Thank you.
propListArray is empty so trying to get the dictionary at any index will return nil, Then when you try to set a value it will cause the error.
You can fix it by creating the dictionary then assigning it to you global dictionary at the correct index.
var propListArray = [Int : [String : String]] ()
let itemArray = dataDictionary["properties"] as! NSArray
for (index, item) in itemArray.enumerate() { {
let propertyID = item["id"]! as! String
let data = ["propertyID": propertyID]
propListArray[index] = data
}
Quick fix:
var propListArray = [Int : [String : String]] ()
let itemArray = dataDictionary["properties"] as! NSArray
var i = 0
for item in itemArray {
let propertyID = item["id"]! as! String
propListArray[i] = ["propertyID": propertyID]
i++
}
However, i++ within the for loop is not idiomatic Swift. In fact, i++ and C-style for loops are going to be removed in Swift 3. It is better to use enumerate():
var propListArray = [Int : [String : String]] ()
let itemArray = dataDictionary["properties"] as! NSArray
for (i, item) in itemArray.enumerate() {
let propertyID = item["id"]! as! String
propListArray[i] = ["propertyID": propertyID]
}
propListArray[0]?["propertyID"]