Order changed when I append values in dictionary from model in Swift - ios

I have grouped data according to date and append values to AppointmentDateModel - tableValues.
As data contain of one same date with multiple appointments data so I grouped them.
But when I append values it automatically sorted or rearrange order by itself.
How can I set order as it is in the dictionary so the order cannot be changed? Or am I grouping them in a right way?
My main models are DownloadEntity and appointmentDownloadModel and then for grouped I use AppointmentDateModel
declaration:
var mDownloadEntity: [DownloadEntity] = []
var tableValues:[AppointmentDateModel] = []
var dict : [Int64:[AppointmentDownloadModel]] = [:]
Appending Code:
mDownloadEntity.forEach { apDate in
print(apDate)
var value = dict[apDate.appdate]
if(value == nil){
dict.updateValue([apDate.appointmentDownloadModel!], forKey: apDate.appdate)
}else{
value?.append(apDate.appointmentDownloadModel!)
dict.updateValue(value!, forKey: apDate.appdate)
}
}
dict.forEach{map in
let appointmentDateModel = AppointmentDateModel(appointmentDate: map.key, entities:map.value)
tableValues.append(appointmentDateModel)
}
Models:
struct AppointmentDownloadModel: Codable{
var appointmentModel: Appointment
var progress: Int = 0
var failedList: [Int: String] = [:]
var isFinished: Bool = false
}
struct DownloadEntity: Codable {
let id: Int
var appdate: Int64
var userId: Int
var dFirmId: Int
var appointmentId: Int
var appointmentDownloadModel: AppointmentDownloadModel?
}
struct AppointmentDateModel: Codable {
let appointmentDate:Int64
var entities:[AppointmentDownloadModel]
}

Related

How to get the struct value from another class?

I want to fetch the offerApplied value from the struct in another class. Here is the struct block:
struct Offer: JsonDeserilizer {
var offerDesC:String = ""
var discount:Double = 0.0
var offerId:String = ""
var offerCode:String = ""
var offerApplied:Int = 0
mutating func deserilize(values: Dictionary<String, Any>?) {
self.offerDesC = values?["offer_desc"] as? String ?? ""
self.discount = values?["discount"] as? Double ?? 0.0
self.offerId = values?["_id"] as? String ?? ""
self.offerCode = values?["offer_code"] as? String ?? ""
self.offerApplied = values?["is_applied"] as? Int ?? 0
}}
And an explanation will be very helpful.
You can create getter function in your struct, that can return specific value as you want. In target class initialise your struct properties (by calling deserilize(), or however you wish) and call the getter function to fetch values.
Update-:
As #Joakim mentioned, your properties are not private, so there is no need to create getter function. You could infact directly refer the property from created object.
struct Offer {
var offerDesC:String = ""
var discount:Double = 0.0
var offerId:String = ""
var offerCode:String = ""
var offerApplied:Int = 0
mutating func deserilize() {
self.offerDesC = "xy"
self.discount = 20
self.offerId = "okkk"
self.offerCode = "12"
self.offerApplied = 245
}
// func returnOfferApplied() -> Int{
// return offerApplied
// }
}
class xyz{
var obj = Offer()
func printOffer(){
obj.deserilize()
print(obj.offerApplied)
}
}
let obj = xyz()
obj.printOffer()
First create struct class at global file.
Look in my example
struct ColorPalette {
static let UEMColor = hexStringToUIColor(hex: "72279C")
static let uemIconPrimary = hexStringToUIColor(hex: "282D68")
}
Access Struct Like this:
ColorPalette.uemIconPrimary

Adding object to object array

I have this code:
struct Calculators
{
var calculators: [Calculator]?
var activeCalculator: Int = -1
var activeSummary: Bool = false
var activeProfits: Bool = false
public mutating func addCalc(calc: Calculator){
self.calculators?.append(calc)
}
}
struct Calculator
{
var priceSum: Float = 0
var weightSum: Float = 0
var pricePerMix: Float = 0
var pricePerPortion: Decimal?
var portionDivider: Float?
var nettoPortionCost: Float?
var profitPerPortion: Float?
var pricePerKgAfterPrepare: Float?
var weightPerPortionInGrams: Float?
var concept : PromoConcepts?
let createTime: Double
var products : [CountedProduct]?
init() {
createTime = NSDate().timeIntervalSince1970 * 1000
}
}
When I'm trying add new object:
var activeCalculators = Calculators()
let calculator = Calculator()
activeCalculators.addCalc(calc: calculator)
to object array ([Calculator]?).
The app does not add this (not working).
Does anyone know how to fix it?
I guess you forgot to create the array:
var calculators: [Calculator]? = [Calculator]()
struct Calculators
{
var calculators: [Calculator]?
var activeCalculator: Int = -1
var activeSummary: Bool = false
var activeProfits: Bool = false
public mutating func addCalc(calc: Calculator){
if calculators == nil {
self.calculators = []
}
self.calculators?.append(calc)
}
}
Just initialize calculators inside the addCalc func, if you still want to have calculators as a nullable var.
If this isn't essential for you, go for the solution of Sh_Khan
You need to init it like this
activeCalculators = [Calculator]()
//
struct Calculators
{
var calculators = [Calculator]()
var activeCalculator: Int = -1
var activeSummary: Bool = false
var activeProfits: Bool = false
public mutating func addCalc(calc: Calculator){
self.calculators.append(calc)
}
}
Your default initialization method didn't not create a Calculator Array.
So when you initialize it like this
var activeCalculators = Calculators(calculators: nil, ...
The add could not be done, because the calculators is actually nil.
You should initialize it like this
var activeCalculators = Calculators(calculators: [Calculator()], ...
Or do something to make it not nil.
The problem is you are trying to insert object into uninitiazed array.
You have two Options:
1.Create & Initialise array
var calculators = [Calculator]()
2.Initialise array before adding object to it.
var activeCalculators = Calculators()
activeCalculators.calculators = [Calculator]()
let calculator = Calculator()
activeCalculators.addCalc(calc: calculator)

How to combine arrays depending on user selection?

I want to see what user selected like the name of book and its assocaited chapters
I did this
struct bookChpt {
var book:[String] = []
var chapter:[[Int]] = []
}
let chptSelected = [bookChpt(book:bookArr,chapter:chptArr)]
var bookArr:[String] = []
var chptArr:[[Int]] = []
I have this in viewDidLoad()
if let bTitle = result.value(forKey: "bookTitle") as? String
{
bookArr.append(bTitle)
}
if let cNo = result.value(forKey: "chpNo") as? [Int]
{
chptArr.append(cNO)
}
print(chptSelected)
I am getting this
bookChpt( book: ["Hobbit", "LOTR"], chapter: [[3,5],4])
but I like to see this
["Hobbit", 3, 5], ["LOTR", 4]
There are a couple of possibilities. You could add a function to the struct to display its contents in the way you want:
struct BookChapter {
var book:[String] = []
var chapter:[[Int]] = []
func display() -> [[Any]] {
var output = [[Any]]()
for i in 0..<book.count {
output.append([book[i], chapter[i]])
}
return output
}
}
Or you could modify the structure of the struct to contain the book and chapters as tuples:
struct BookChapter {
var book:[(String, [Int])]
}
Going a bit further, anywhere you see a loop - such as in the display function above - you might also consider using map to achieve the same thing:
func display() -> Any {
return book.enumerated().map { $0.element + " " + chapter[$0.offset].description }
}
If you use an Dictionary like this, you can print the key and value whatever way you wanted.
var bookChapters = [String: [Int]]()
bookChapters["Hobbit"] = [1,2,3]
bookChapters["Hobbit"]?.append(contentsOf: [4])
for (book, chapter) in bookChapters {
print("\(book): \(chapter)")
}
Change your struct to
struct BookChapt {
var book: String = ""
var chapter: [Int] = []
}
and in viewDidLoad()
var bookName = ""
var chapters:[Int] = []
if let bTitle = result.value(forKey: "bookTitle") as? String
{
bookName = bTitle
}
if let cNo = result.value(forKey: "chpNo") as? [Int]
{
chapters = cNo
}
let chptSelected = BookChapt(book: bookName, chapter: chapters)
print(chptSelected)

Realm object changed, another copy of that object has changed too, why?

I am stuck in a problem. Let's assume I have this Realm Model:
class Table: Object {
dynamic var id = 0
dynamic var x: Int = 0
dynamic var y: Int = 0
dynamic var width:Int = 0
dynamic var height: Int = 0
dynamic var text: String = ""
dynamic var color: String = ""
dynamic var type: String = ""
let food = List<Food>()
override static func primaryKey() -> String {
return "id"
}
}
class Food : Object {
dynamic var id: Int = 0
dynamic var name = ""
dynamic var ingredients: String = "" // bigger text field
dynamic var size: Int = 0 // none, small, medium, big size
dynamic var price: Float = 0.0
dynamic var category: Category?
let additionalIngredients = List<Ingredient>()
override static func primaryKey() -> String {
return "id"
}
}
Let's say I have one table and added 2 times the same food on that table like so :
try! realm.write(){
table.food.append(food) // A
table.food.append(food) // B
realm.add(table, update: true)
}
If I change the additionalIngredients for food A , also at the same food B changes its values. I am doing that changes with this transaction :
try! realm.write(){
table.food.first!.additionalIngredients.removeAll()
for ingredient in ingredientsToAdd{
table.food.first!.additionalIngredients.append(ingredient)
}
realm.add(table, update: true)
}
I guess I am doing something wrong regarding the reference/instance, can someone give me a hint?
Thanks in advance!
List.append() adds the object itself to the list and not a copy of the object, so you only have one Food object.

Casting struct to NSUserDefaults in Swift?

Is there a way I can cast this Swift data set in someway to a form that is acceptable to NSUserDefauts? i.e. NSObject NSSet? (p.s. I realize NSUserDefaults isn't for this type of data, but I'm just testing)
struct Users {
var name: String = ""
var stores: [Store]
}
struct Store {
var name: String = ""
var clothingSizes = [String : String]()
}
init() {
let userDefaults = NSUserDefaults.standardUserDefaults()
if let usersPeople = userDefaults.valueForKey("Users") as?
I think you can use Dictionary. You'll need to make method to wrap data to struct and vice versa.
For example:
var users : [String: AnyObject]()
users["name"] = "SomeName"
users["stores"] = yourStoreArray
NSUserDefaults.standardUserDefaults().setObject(users, forKey: "Users")
something like that.
And when you need to get struct
if let myDictionaryFromUD = userDefaults.objectForKey("Users") as? [String:AnyObject]{
self.users = Users(myDictionaryFromUD["name"], stores: myDictionaryFromUD["stores"] as! [Store])
}
I aslo assume that you will save to userDefaults array of Users. In this case, you will save [[String: AnyObject]] but mechanics the same.
I don't know that this is the best way to do this but you can try this.
struct Users {
var name: String = ""
var stores: [Store]
}
struct Store {
var name: String = ""
var clothingSizes = [String : String]()
}
var Advert = [Users]()
init() {
NSUserDefaults.standardUserDefaults().setObject(Advert[0].name, forKey: "NameYouWant")
}

Resources