Cannot add an append an array into a dictionary that has an empty array - ios

I have a Profile Data singleton class as follows.
I am trying to store data into an empty array in a dictionary .
After appending data to the array also the count of the array is 0.
class ProfileData{
static let sharedInstance = ProfileData()
var artistProfileDict = [String : Profile]()
var loggedInUserProfile = Profile(artistName: "John Smith", artistDescription: "Admiral of New England, English soldier, explorer, and author.", totalLikes: "174", totalViews: "200", totalFollowing: "100",totalFollowers:"50",imageUrl:"image_singer", feeds:[] )
private init() {
getProfilesDictionary()
}
func getProfilesDictionary()->[String: Profile]{
artistProfileDict["John Smith"] = loggedInUserProfile
return artistProfileDict
}
func add(array: Feed, artistName: String) {
artistProfileDict[artistName]!.feeds.append(array)
}
}
In another view Controller I am trying to add an array to the empty array in the dictionary as follows
let newFeed = Feed(profilePicture: "image",artistName: "New",
videoUrl: "url",videoTitle:"New", videoViews: "160",likes:
"200",shoutouts: "200",comments: [],votes: "50", dateCreated: Date(),
userActivity :"This user liked your video")
ProfileData.sharedInstance.add(array: newFeed,artistName:"John Smith")
After appending the array to the empty array in the dictionary I still get the count of the array as 0.
I am not able to figure out the problem here. Any help will appreciated . Thank you.
Profile class
struct Profile {
var artistName: String
var artistDescription: String
var totalLikes: String
var totalViews: String
var totalFollowing: String
var totalFollowers: String
var imageUrl: String
var feeds : [Feed]
init(artistName: String,artistDescription:String,totalLikes:String,totalViews:String,totalFollowing:String,totalFollowers:String,imageUrl:String, feeds:[Feed]) {
self.artistName = artistName
self.artistDescription = artistDescription
self.totalLikes = totalLikes
self.totalViews = totalViews
self.totalFollowing = totalFollowing
self.totalFollowers = totalFollowers
self.imageUrl = imageUrl
self.feeds = feeds
}
}

It's working fine
ProfileData.sharedInstance.add(array: newFeed,artistName:"John Smith")
ProfileData.sharedInstance.artistProfileDict["John Smith"]?.feeds.count // 1
Probably you are using wrong class ArtistProfileData instead of ProfileData.

Related

Find out common value from two different Type Array

I have two Array with different Data Types
Assume Array1 is an [String] array of String
Assume Array 2 is an [Custom Objects] array of Struct
Pls find a code
struct ScanData{
var serialNo : String!
var intNo : String!
init(serialNo : String, intNo : String) {
self.serialNo = serialNo
self.intNo = intNo
}
}
var validScannedData : [String] = []
var inValidScannedData : [String] = []
var arrayObj = [ScanData(serialNo: "12220116033", intNo: "SN6AT4.270"),ScanData(serialNo: "12198144025", intNo: "SN6AT4.280"),ScanData(serialNo: "12222383027", intNo: "SN6AT4.130"),ScanData(serialNo: "12198213032", intNo: "SN6AT5.260"),ScanData(serialNo: "", intNo: "")]
//print(arrayObj)
//ScanData(serialNo: "12199690049", intNo: "SN6AT6U100")
var localArray = ["12220116033","12198144025","12222383027","12198213032","12199690049"]
let tempArray = arrayObj.filter { data in
return data.serialNo != "" || data.intNo != ""
}
print(tempArray.count)
Now we want to get common values from localArray and tempArray by matching serialNo key
Finally i want to have Array of String Format in validScannedData object
Expected Output :
Valid data : ["12220116033","12198144025","12222383027","12198213032"]
Invalid data : ["12199690049"]
I tried this but its prints custom object array
let a = tempArray.filter () { localArray.contains($0.serialNo) }
print(a)
Thanks in advance
Use forEach to iterate your element and then check and append to the according to array.
localArray.forEach { number in
arrayObj.contains(where: {$0.serialNo == number}) ? validScannedData.append(number) : inValidScannedData.append(number)
}
print(validScannedData)
print(inValidScannedData)

App crashes when I am trying to saved data in my model

I am developing an App using Realm. At some point in my app when I try to manipulate my model, my app crashed in an unexpected way. Here is what the stack trace said
Can only add, remove, or create objects in a Realm in a write transaction - call beginWriteTransaction on an RLMRealm instance first
What I am trying to do :
lets break down my problem in parts.following is my model of app
#objcMembers public class ClassGroup : Object , Codable {
dynamic var Id : Int? = ""
dynamic var ClassName : String? = ""
dynamic var TeacherId : Int = 0
dynamic var Teachers : [TeacherMdoel]? = []
}
#objcMembers public class TeacherModel : Object , Codable {
dynamic var Id : String? = ""
dynamic var Name : String? = ""
dynamic var ClassId : Int = 0
dynamic var Students : [StudentClass]? = []
}
#objcMembers public class StudentModel : Object , Codable {
dynamic var Id : String? = ""
dynamic var Name : String? = ""
dynamic var ClassId : Int = 0
dynamic var TeacherId : Int = 0
}
now I am trying to get the list of all classes like this from realm (after saving them to realm )
let mClassLists = mDbHelper.realmObj.objects(ClassGroup.self)
Now here I get exception/error. What I am doing is, I am trying to populate my UITableView with some data that consist of all of the above models. I am fetching data and saving them in my model and trying to supply that list to UITableView but my app crash with the error I mentioned above
let mClassLists = mDbHelper.realmObj.objects(ClassGroup.self)
let classLists = Array (mClassLists)
for classModel in classLists {
let resultPredicateTeachers = NSPredicate(format: "ClassId == %#", classModel.Id)
let mTeachersList = mDbHelper.realmObj.objects(TeacherModel.self).filter(resultPredicateTeachers)
if(mTeachersList.count > 0){
var listTeachers : [TeacherModel] = []
for teacherModel in mTeachersList {
let resultPredicateStudent = NSPredicate(format: "TeacherId == 29")
let mStudentList = mDbHelper.realmObj.objects(StudentModel.self).filter(resultPredicateStudent)
if(mStudentList.count > 0){
let studentsList = Array(mStudentList)
teacherModel.Students = studentsList[0]
}
listTeachers.append(savedDetailItem)
}
classModel.Teachers? = (listTeachers)
listClassModel.append(classModel)
}
}
**In the Above code you can see that I am gathering data on behalf of Ids and saving the resultant arrays in the model. So I am getting error in the following line
**
teacherModel.Students = studentsList[0]
now I really do not understand why it is happening? I am not saving data in realm, I am saving in my model, still I am getting error.
In Realm database, if you want to modify any model (save new data or update), the operation should be performed in a write transaction:
try! realm.write {
realm.add(<your_model_objects>)
}

How to update Firebase with struct

I have a struct EventDate and am trying to update a reference in Firebase.
struct EventDate {
var club: String = ""
var date: String = ""
var eventText: String = ""
var free: String = ""
var monthYear: String = ""
}
My update function throws lldb. I guess because the keys are no Strings(?)
func updateEvent(_ backendlessUserObjectID: String, event: EventDate) {
let reference = firebase.child("eventDates").child(backendlessUserObjectID).child(event.date)
reference.setValue(event) { (error, ref) -> Void in
if error != nil {
print("\(error)")
}
} // lldb here
}
If I change the function to the following, everything is fine (because Keys and Values are now Strings?)
func updateEvent(_ backendlessUserObjectID: String, event: EventDate) {
let item: NSMutableDictionary = ["club" : event.club,
"date" : event.date,
"eventText" : event.eventText,
"free" : event.free,
"monthYear" : event.monthYear]
let reference = firebase.child("eventDates").child(backendlessUserObjectID).child(event.date)
reference.setValue(item) { (error, ref) -> Void in
if error != nil {
print("\(error)")
}
}
}
Am I right that I receive lldb because the keys from my models are not Strings? Or what am I missing and how will I be able to save the values into my Firebase using my model without creating the NSMutableDictionary? Help is very appreciated.
PS: print(event.date) = 201610120200000000 -> the desired value for .child
Firebase data exists in a JSON format which can be thought of as key:value pairs. The keys must be strings and the values can be any of the for data types mentioned in Dravidians answer (which is a correct answer and should be accepted). I would like to add some additional comments that may help as well.
There are times when you want to use a structure in code and that can't be written to Firebase directly - you need some way to get the data out of the structure into something Firebase likes - which is a Dictionary.
Heres an example (Swift 3, Firebase 2.x)
struct EventDate {
var club: String = ""
var date: String = ""
var eventText: String = ""
var free: String = ""
var monthYear: String = ""
func getDict() -> [String:String] {
let dict = ["club": self.club,
"date": self.date,
"eventText": self.eventText,
"free": self.free,
"monthYear": self.monthYear
]
return dict
}
}
var event = EventDate()
event.club = "Wimbledon"
event.date = "20161023"
event.eventText = "Special Tennis Event"
event.free = "Free"
event.monthYear = "10/2016"
let ref = self.myRootRef.child(byAppendingPath: "events")!
let eventRef = ref.childByAutoId() //Firebase 2.x
eventRef?.setValue( event.getDict() )
This results in a node being written to Firebase that looks like this
"events" : {
"-KUli8oiM_KKw8GZ0MMm" : {
"club" : "Wimbeldon",
"date" : "20161023",
"eventText" : "Special Tennis Event",
"free" : "Free",
"monthYear" : "10/2016"
}
}
No it has nothing to do with the type of keys that you are trying to save in your Firebase Database its just that struct is a dataModel or to be precise a physically grouped list of variables which you initialise with some custom Data, and you can only save four types of values types in your Firebase Database:-
NSDictionary
NSArray
NSNumber
NSString
Look up the docs :- Read And Write data, Firebase- iOS
So when you cast your values in a NSMutableDictionary, you come clean of struct. And struct and class is not recognisable by the Firebase Database.

How do I create a dictionary from an array of objects in swift 2.1?

I have an array of type "drugList", and they are derived from a struct "DrugsLibrary":
struct DrugsLibrary {
var drugName = ""
var drugCategory = ""
var drugSubCategory = ""
}
var drugList = [DrugsLibrary]()
//This is the dictionary i'm trying to build:
var dictionary = ["": [""," "]]
My data model is initialized using this function:
func createDrugsList() {
var drug1 = DrugsLibrary()
drug1.drugName = "drug1"
drug1.drugCategory = "Antibiotics"
drug1.drugSubCategory = "Penicillins"
self.drugList.append(drug1)
var drug2 = DrugsLibrary()
drug2.drugName = "drug2"
drug2.drugCategory = "Antibiotics"
drug2.drugSubCategory = "Penicillins"
self.drugList.append(drug2)
var drug3 = DrugsLibrary()
drug3.drugName = "drug2"
drug3.drugCategory = "Antibiotics"
drug3.drugSubCategory = "Macrolides"
self.drugList.append(drug3)
}
my problem is that i'm trying to create a dictionary from the drugList where the key is the drugSubCategory and the value is the drug name. The value should be an array if there are several drugs in this subcategory
for example, the dictionary should look something like this for this example:
dictionary = [
"Penicillins": ["drug1","drug2"]
"Macrolides": ["drug3"]
]
I tried this method:
for item in drugList {
dictionary["\(item.drugSubCategory)"] = ["\(item.drugName)"]
}
this gave a dictionary like this, and it couldn't append drug2 to "Penicllins":
dictionary = [
"Penicillins": ["drug1"]
"Macrolides": ["drug3"]
]
So I tried to append the items into the dictionary using this method but it didn't append anything because there were no common items with the key "" in the data model:
for item in drugList {
names1[item1.drugSubCategory]?.append(item1.drugName)
}
Anyone knows a way to append drug2 to the dictionary?
I would appreciate any help or suggestion in this matter.
You need to create a new array containing the contents of the previous array plus the new item or a new array plus the new item, and assign this to your dictionary:
for item in drugList {
dictionary[item.drugSubCategory] = dictionary[item.drugSubCategory] ?? [] + [item.drugName]
}
You can use .map and .filter and Set to your advantage here. First you want an array of dictionary keys, but no duplicates (so use a set)
let categories = Set(drugList.map{$0.drugSubCategory})
Then you want to iterate over the unique categories and find every drug in that category and extract its name:
for category in categories {
let filteredByCategory = drugList.filter {$0.drugSubCategory == category}
let extractDrugNames = filteredByCategory.map{$0.drugName}
dictionary[category] = extractDrugNames
}
Removing the for loop, if more Swifty-ness is desired, is left as an exercise to the reader ;).
I have two unrelated observations:
1) Not sure if you meant it as an example or not, but you've initialized dictionary with empty strings. You'll have to remove those in the future unless you want an empty strings entry. You're better off initializing an empty dictionary with the correct types:
var dictionary = [String:[String]]()
2) You don't need to use self. to access an instance variable. Your code is simple enough that it's very obvious what the scope of dictionary is (see this great writeup on self from a Programmers's stack exchange post.
Copy this in your Playground, might help you understand the Dictionaries better:
import UIKit
var str = "Hello, playground"
struct DrugsLibrary {
var drugName = ""
var drugCategory = ""
var drugSubCategory = ""
}
var drugList = [DrugsLibrary]()
//This is the dictionary i'm trying to build:
var dictionary = ["":""]
func createDrugsList() {
var drug1 = DrugsLibrary()
drug1.drugName = "drug1"
drug1.drugCategory = "Antibiotics"
drug1.drugSubCategory = "Penicillins"
drugList.append(drug1)
var drug2 = DrugsLibrary()
drug2.drugName = "drug2"
drug2.drugCategory = "Antibiotics"
drug2.drugSubCategory = "Penicillins"
drugList.append(drug2)
var drug3 = DrugsLibrary()
drug3.drugName = "drug2"
drug3.drugCategory = "Antibiotics"
drug3.drugSubCategory = "Macrolides"
drugList.append(drug3)
}
createDrugsList()
print(drugList)
func addItemsToDict() {
for i in drugList {
dictionary["item \(i.drugSubCategory)"] = "\(i.drugName)"
}
}
addItemsToDict()
print(dictionary)

return random dictionary items in swift

I'm trying to return a random name and a random email from this function have got so far but I'm wondering what should I be returning here obviously as I want to return a tuple it needs to be 2 string values which I need randomly from my function
func randomAuthor () -> (name : String, email : String) {
struct Author {
var name : String
var email : String
}
let firstAuthor = Author(name: "jon", email: "jonsEmail")
let secondAuthor = Author(name: "richard", email: "richardsEmail")
let thirdAuthor = Author(name: "steve", email: "stevesEmail")
let fourthAuthor = Author(name: "simon", email: "simonsEmail")
let fifthAtouh = Author(name: "wes", email: "wesEmail")
var dictionary = [firstAuthor.name : firstAuthor.email, secondAuthor.name : secondAuthor.email, thirdAuthor.name : thirdAuthor.email, fourthAuthor.name : fourthAuthor.email, fifthAuthor.name : fithAtouh.email]
var unsignedDictionaryCount = UInt32(dictionary.count)
var unsignedRandom = arc4random_uniform(unsignedDictionaryCount)
var random = unsignedRandom
return()
}
any help appreciated
thanks
Random value from an Dictionary in several steps:
Create your Dictionary
Get a random Int using arc4random_uniform
Used this random Int to get a random key (using keys), and get its value
Return them, and you are done !
var dictionary : [String:String] = [firstAuthor.name : firstAuthor.email, secondAuthor.name : secondAuthor.email, thirdAuthor.name : thirdAuthor.email, fourthAuthor.name : fourthAuthor.email]
let index: Int = Int(arc4random_uniform(UInt32(dictionary.count)))
let value = Array(dictionary.values)[index]
let key = Array(dictionary.keys)[index]
let value = dictionary[key]
return (key, value!)
Use your random integer as an index into dictionary.keys. This will fetch you the name that you can use to look up your email.

Resources