Adding object to object array - ios

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)

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

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

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]
}

Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) in project

I just started Swift and I am having problems.
I want pagination, and I coded this.
model:
struct MoreListAppand {
var MoreNoticeListModel : [MoreNoticeListModel] = []
mutating func addTask(task: MoreNoticeListModel){
MoreNoticeListModel.append(task)
}
}
struct MoreNoticeListModel {
var pageInfo : PageInfoFragmentModel? = nil
var totalCount : Int = 0
var edges: [NoticeInfoModel] = []
mutating func map(MoreNoticeListModel item: NoticeList){
self.pageInfo = nil
let pageData = item.pageInfo
var pageModel = PageInfoFragmentModel()
pageModel.map(item: pageData.fragments.pageInfoFragment)
self.pageInfo = pageModel
self.totalCount = item.totalCount
print("NoticeList totalCount == ", self.totalCount)
self.edges.removeAll()
for edge in item.edges! {
var edgeModel = NoticeInfoModel()
edgeModel.map(NoticeInfoModel:(edge?.fragments.edgesInfoFragment)!)
self.edges.append(edgeModel)
}
}
}
struct PageInfoFragmentModel {
// var hasNextPage : Bool << If I do not comment, an error will appear.(Missing argument for parameter 'hasNextPage' in call)
// var hasPreviousPage : Bool
var startCursor : String = ""
var endCursor : String = ""
mutating func map(item:PageInfoFragment) {
// self.hasNextPage = item.hasNextPage
// self.hasPreviousPage = item.hasPreviousPage
self.startCursor = item.startCursor
self.endCursor = item.endCursor
}
}
struct NoticeInfoModel {
var cursor : String = ""
var id : String = ""
var type: noticeType = .URGENT
var title: String = ""
var createdAt: String = ""
mutating func map(NoticeInfoModel item: EdgesInfoFragment){
self.cursor = item.cursor
self.id = item.node.id
self.type = noticeType(rawValue: item.node.type.rawValue)!
self.title = item.node.title
self.createdAt = item.node.createdAt
print("NoticeList title == ", self.title)
print("NoticeList type == ", self.type)
}
}
and
#objc func myAction(_ sender : AnyObject) {
//sever connect
MoreAPI.shared.getNoticeList(first: 10, last: 0, offset: 0, after: "MjAxNy0xMi0wNVQxNzo1MDozMVo=", before: ""){
[unowned self] (noticeItemLists) in
self.noticeAddListDataModel?.addTask(task: noticeItemLists)
let indexPath:IndexPath = IndexPath(row:((self.noticeAddListDataModel?.MoreNoticeListModel.count)!), section:0) << this is error line
self.noticeListTable.reloadData()
}
}
self.noticeAddListDataModeldefined here
class MoreNoticeViewController: UIViewController {
var noticeAddListDataModel : MoreNoticeListModel? = nil
}
why PageInfoFragmentModel want "hasNextPage" parameter argument..?
I got error
"let indexPath:IndexPath = IndexPath(row:((self.noticeAddListDataModel?.MoreNoticeListModel.count)!), section:0)" line.
I do not know why I get this error....
The error Missing argument for parameter 'hasNextPage' in call states that you have a variable defined in the struct and not initialized. Since it is not initialized, you have to pass its value in the constructor call,i.e. where you are calling PageInfoFragmentModel(), you have to call PageInfoFragmentModel(hasNextPage: ). This constructor is defined by default by swift, if no constructor is defined. So to remove the bug, either you give it a value or make it an optional or pass its value in initialization. Read this : https://docs.swift.org/swift-book/LanguageGuide/Initialization.html for more info.
Follow naming convention, which is for variables camelCase.
struct MoreListAppand {
var MoreNoticeListModel : [MoreNoticeListModel] = []
mutating func addTask(task: MoreNoticeListModel){
MoreNoticeListModel.append(task)
}
}
here var var MoreNoticeListModel is Struct name, change it to var moreNoticeListModel.
1. why PageInfoFragmentModel want "hasNextPage" parameter argument..?
That is a model written by someone who added that variable that is why it is there, we won't be able to tell about that. If there is no use of those variables comment them.
2.
noticeAddListDataModel doesn't have any reference to MoreNoticeListModel instead it is of same type, you can't get count property from a model.
Maybe this is what you need ? self.noticeAddListDataModel?.totalCount or self.noticeAddListDataModel?.edges.count.

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.

Resources