I have the following code:
var rawTypeArray = [[String: String]]()
rawTypeArray = NSArray(contentsOfFile: finalPathString) as! [[String: String]]
for eachType: [String: String] in rawTypeArray {
let setType = SetTypes(value: eachType)
try! realm.write {
realm.add(setType)
}
let all = realm.objects(SetTypes.self)
print (all)
}
the values of the dictionary are not passed to the realm object.
All the object are initialized with the default values. The dictionary values are ignored, what's wrong?
Related
until version 10.7.6 of Realm I could convert to dictionary and then to json with this code below, but the ListBase class no longer exists.
extension Object {
func toDictionary() -> NSDictionary {
let properties = self.objectSchema.properties.map { $0.name }
let dictionary = self.dictionaryWithValues(forKeys: properties)
let mutabledic = NSMutableDictionary()
mutabledic.setValuesForKeys(dictionary)
for prop in self.objectSchema.properties as [Property] {
// find lists
if let nestedObject = self[prop.name] as? Object {
mutabledic.setValue(nestedObject.toDictionary(), forKey: prop.name)
} else if let nestedListObject = self[prop.name] as? ListBase { /*Cannot find type 'ListBase' in scope*/
var objects = [AnyObject]()
for index in 0..<nestedListObject._rlmArray.count {
let object = nestedListObject._rlmArray[index] as! Object
objects.append(object.toDictionary())
}
mutabledic.setObject(objects, forKey: prop.name as NSCopying)
}
}
return mutabledic
}
}
let parameterDictionary = myRealmData.toDictionary()
guard let postData = try? JSONSerialization.data(withJSONObject: parameterDictionary, options: []) else {
return
}
List now inherits from RLMSwiftCollectionBase apparently, so you can check for that instead. Also, this is Swift. Use [String: Any] instead of NSDictionary.
extension Object {
func toDictionary() -> [String: Any] {
let properties = self.objectSchema.properties.map { $0.name }
var mutabledic = self.dictionaryWithValues(forKeys: properties)
for prop in self.objectSchema.properties as [Property] {
// find lists
if let nestedObject = self[prop.name] as? Object {
mutabledic[prop.name] = nestedObject.toDictionary()
} else if let nestedListObject = self[prop.name] as? RLMSwiftCollectionBase {
var objects = [[String: Any]]()
for index in 0..<nestedListObject._rlmCollection.count {
let object = nestedListObject._rlmCollection[index] as! Object
objects.append(object.toDictionary())
}
mutabledic[prop.name] = objects
}
}
return mutabledic
}
}
Thanks to #Eduardo Dos Santos. Just do the following steps. You will be good to go.
Change ListBase to RLMSwiftCollectionBase
Change _rlmArray to _rlmCollection
Import Realm
I'm trying to fetch data from my firebase database, such that i can store it in a form of dictionary which is a type [String: [Any]] where key is the unique id and the value is a type of array which has the data stored under uniqueID->Question.
func getData(currUser: String, completion: #escaping (([String : [Any]]) -> ())) {
var newArray = [String : [Any]]()
let ref = Database.database().reference(fromURL: "MYURL").child("users/\(currUser)/Questions").observeSingleEvent(of: .value, with: { (snap) in
let enumerator = snap.children
while let rest = enumerator.nextObject() as? DataSnapshot, let value = rest.value{
newArray.updateValue([value], forKey: rest.key)
}
completion(newArray)
})
}
this completion block gives me:
["-LlpbizBpQTXOQ6zv0zd": [{
Qusetion = (
Hello,
test,
kkkkkkkkkkk
);
}]]]
Instead how can i get
["-LlpbizBpQTXOQ6zv0zd": [Hello,test,kkkkkkkkkkk]]
You're converting the value to a string, while it's actually a JSON object. That's why the value in your dictionary is a JSON object.
To only get the question text under Qusetion (typo?), you'll need to loop over that child snapshot and collect the individual values. Something like:
var newArray = [String : [Any]]()
let ref = Database.database().reference(fromURL: "MYURL").child("users/\(currUser)/Questions").observeSingleEvent(of: .value, with: { (snap) in
let enumerator = snap.children
while let rest = enumerator.nextObject() as? DataSnapshot {
var values = [String]
let valueEnumerator = rest.childSnapshot(atPath: "Qusetion").children
while let valueRest = valueEnumerator.nextObject() as? DataSnapshot, let value = rest.value {
values.append(value)
}
newArray.updateValue([values], forKey: rest.key)
}
completion(newArray)
})
Hi im trying to access the items in the legs array inside my plist
I want to be able to get the values for key = "title" from the legs array from this plist
I already have the method to get the values from the dictionary called abs which is the following code
let path = Bundle.main.path(forResource:"Exercise", ofType: "plist")
let dict:NSDictionary = NSDictionary(contentsOfFile: path!)!
if (dict.object(forKey: "levels") != nil) {
if let levelDict:[String : Any] = dict.object(forKey: "levels") as? [String : Any] {
for (key, value) in levelDict {
if ( key == "something") {
print(value)
}
}
}
}
However i have no idea how to access the legs array to get item titles
While reaching to the legs array which is of type [[String:String]] in your case with three elements and each index having two key pair values. You can loop over that index and get your values then iterate over to others.
let yourLegsArray:AnyObject = dict.object(forKey: "legs")! as AnyObject
then iterate over yourLegsArray and get the inside values of the Dict.
So I managed to find an answer to my original question
let path = Bundle.main.path(forResource: "Exercise", ofType: "plist")
let dict = NSDictionary(contentsOfFile: path!)!
let levelArray:AnyObject = dict.object(forKey: "legs")! as AnyObject
if let nsArray:NSArray = levelArray as? NSArray{
var levelDict:AnyObject = nsArray[1] as AnyObject //currentLevel is an Int
//then finally I could get data from a dictionary in the array
let Title = levelDict["title"] as AnyObject? as! String
print(Title)
}
So now this will print the second item in legs array which is "leg 2"
Tried the 'is' keyword.
// Initialize the dictionary
let dict = ["name":"John", "surname":"Doe"]
// Check if 'dict' is a Dictionary
if dict is Dictionary {
print("Yes, it's a Dictionary")
}
This will give an error saying "'is' is always true".
I just want to check if an object is a dictionary. It can be with any key any value pairs.
The key is hashable and it is not accepting the Any keyword.
If you want to check if an arbitrary object is a dictionary first of all you have to make the object unspecified:
let dict : Any = ["name":"John", "surname":"Doe"]
Now you can check if the object is a dictionary
if dict is Dictionary<AnyHashable,Any> {
print("Yes, it's a Dictionary")
}
But this way is theoretical and only for learning purposes. Basically it's pretty silly to cast up a distinct to an unspecified type.
If you just want to check if your object is Dictionary you can just do this:
if let dictionary = yourObject as? Dictionary{
print("It is a Dictionary")
}
Put this in a playground:
import UIKit
// Create a dictionary and an array to convert to and from JSON
let d = ["first": "Goodbye", "second": "Hello"]
let a = [1, 2, 3, 4, 5]
let dictData = try! JSONSerialization.data(withJSONObject: d, options: [])
let arrayData = try! JSONSerialization.data(withJSONObject: a, options: [])
// Now that we have set up our test data, lets see what we have
// First, some convenience definitions for the way JSON comes across.
typealias JSON = Any
typealias JSONDictionary = [String: JSON]
typealias JSONArray = [JSON]
// Lets see what we have
let dict = try! JSONSerialization.jsonObject(with: dictData, options: [])
let array = try! JSONSerialization.jsonObject(with: arrayData, options: [])
// testing functions
func isDictionary(_ object: JSON) -> Bool {
return ((object as? JSONDictionary) != nil) ? true : false
}
func isArray(_ object: JSON) -> Bool {
return ((object as? JSONArray) != nil) ? true : false
}
// The actual tests
isDictionary(dict) // true
isArray(dict) // false
isDictionary(array)// false
isArray(array) // true
JSON dictionaries arrays have specific types
I prefer using if let or guard let while parsing JSON objects
if let dict = jsonObject as? [AnyHashable:Any] {
print("Yes, it's a Dictionary")
}
guard let dict = jsonObject as? [AnyHashable:Any] else {
print("No, it's not a Dictionary")
return
}
Simply use is operator to check type conformance.
Here's a little snippet where I check if it's a Dictionaryor an Array
let dict = ["name":"John", "surname":"Doe"]
let array = [ "John", "Doe" ]
if dict is Dictionary<String, String>
{
print("Yes, it's a Dictionary")
}
else
{
print("No, It's other thing")
}
if array is Array<String>
{
print("Yes, it's a Array")
}
else
{
print("No, It's other thing")
}
I would like to make an Optional Dictionary Variable inside of a Class so that when I create an instance I don't HAVE to add that argument...
example
class Stuff {
var dictionary: [String: Double]?
init(dictionary: [String:Double]?=["":0]){
}
}
var instance1 = Stuff(dictionary:["length":1.5])
var array: [Stuff] = [instance1, instance2]
let arraySet = (array[indexPath.row])
let X = arraySet.dictionary!
cell.Label.text = "\(X)"
This works but when i assign it to a cell.label.text the output shows Brackets...
"[length:1.5]"
How can i get rid of the brackets???
It's quite complicated to get rid of the brackets, because the key/value pair must be extracted out of the dictionary:
class Stuff {
var dictionary: [String: Double]?
init(dictionary: [String:Double]?=["":0.0]){
self.dictionary = dictionary
}
}
let instance = Stuff(dictionary:["length":1.5])
if let dict = instance.dictionary where dict.count > 0 {
let key = dict.keys.first!
let value = dict[key]!
label.text = "\(key) : \(value)"
}
If you create the dictionary with non-optional literals, consider to declare the variable dictionary as non-optional