Array of object have further inner array of object - ios

My class
class ScoreModel {
var playerId: Int?
var holeScores: [HoleScore]?
}
Other Class
class HoleScore {
var holeScore: Int?
}
I have these classes one is ScoreModel class which can have Array of objects of HoleScore
let scoreList = [ScoreModel]()
scoreList[0].holeScores![0].holeScore = 3
When i update or change holeScore for scoreList[0].holeScores[0] it changes it for all the scoreList[forAllIndexes].holeScores[0]. I just want to change the inner array prams for given index of outer array but it changes all the holeScore values when ever update.

This appends the same object , so change in one reflects to others
var item = HoleScore()
for i in 0...5
{
item. holeScore = i
scoreList[0].holeScores.append(item)
}
//
This appends different objects , so change in one doesn't reflects to others
for i in 0...5
{
var item = HoleScore()
item. holeScore = i
scoreList[0].holeScores.append(item)
}

Just solved my problem converting my classes to struct .I just did not know how to deal with this reference types in a nested sub arrays .So I used struct
struct ScoreModel {
var playerId: Int?
var holeScores: [HoleScore]?
}
struct HoleScore {
var holeScore: Int?
}
Now setting value for a specific inner index will not effect others
let scoreList = [ScoreModel]()
scoreList[0].holeScores![0].holeScore = 3

Related

How to update object in both array if I use separate array for search result?

I want add search functionality in my listing screen. Every item in listing is not view-only but, say for example an object whose few properties are changing based on user action.
To add search functionality, the general way is to keep separate array for search result. Now, in my case user can either alter few values of object from either by searching or without searching. In that case, I will have to update object in both the array based on id of that object but this solution doesn't seems to be proper.
What is the proper way to update the model in this case?
Here is my object
class Course : NSObject
{
var courseId : Int = 0
var name : String = ""
var chapters : [Chapter] = []
var estimatedTime : Int = 0
// Values which will be altered
var userSpentTime : Int = 0
var status : CourseStatus = .pending // Enum
init(_ json: Any?)
{
guard let data = json as? Dictionary else { return }
/* Assignment of values from JSON */
...
...
}
}

Sometimes Classes treat like structures in swift?

for eg:-
In class DishPostedVC, I have an array of model:-
var finalDatesOfDish : [DishActivationDateTimeModel]?
If i pass this variable (finalDatesOfDish) to class DishActivationVC, and do some deletion operation in class DishActivationVC, and if i go back again to class DishPostedVC, then i am getting data after deletion not the actual data, but i am just coming back not passing any data.
I don't know why but this situation occurred one more time earlier with model array, its so strange, how's it possible?
can u tell me what shld i do?
class DishActivationDateTimeModel {
var dayDate: Date? = nil
var dayDateStr: String = ""
var servingsLeft: String = ""
var firstSlotPostedDishId: String = ""
var secondSlotPostedDishId: String = ""
var startTimeDateForFirstSlot: Date? = nil
var startTimeStringForFirstSlot: String = ""
var endTimeDateForFirstSlot: Date? = nil
var endTimeStringForFirstSlot: String = ""
var startTimeDateForSecondSlot: Date? = nil
var startTimeStringForSecondSlot: String = ""
var endTimeDateForSecondSlot: Date? = nil
var endTimeStringForSecondSlot: String = ""
}
It's my model
class DishActivationDateTimeModel {
var dayDate: Date? = nil
var dayDateStr: String = ""
var servingsLeft: String = ""
var firstSlotPostedDishId: String = ""
var secondSlotPostedDishId: String = ""
var startTimeDateForFirstSlot: Date? = nil
var startTimeStringForFirstSlot: String = ""
var endTimeDateForFirstSlot: Date? = nil
var endTimeStringForFirstSlot: String = ""
var startTimeDateForSecondSlot: Date? = nil
var startTimeStringForSecondSlot: String = ""
var endTimeDateForSecondSlot: Date? = nil
var endTimeStringForSecondSlot: String = ""
init(_ object : DishActivationDateTimeModel) {
self.dayDate = object.dayDate
self.dayDateStr = object.dayDateStr
// ....
// ....
self.endTimeStringForSecondSlot = object.endTimeStringForSecondSlot
}
}
extension Array where Element : DishActivationDateTimeModel {
func copyModelArray() -> [DishActivationDateTimeModel] {
var array : [DishActivationDateTimeModel] = []
for object in self {
array.append(DishActivationDateTimeModel(object))
}
return array
}
}
If you don't want to make changes in your main data then copy your
model array using copyModelArray method. And use your operational
model array. So, its not affect to your main model data array.
In Swift structs and classes give you both value and reference-based constructs for your objects. Structs are preferred for objects designed for data storage like Array. Structs also help remove memory issues when passing objects in a multithreaded environment. Classes, unlike structs, support inheritance and are used more for containing logic like UIViewController. Most standard library data objects in Swift, like String, Array, Dictionary, Int, Float, Boolean, are all structs, therefore value objects. The mutability of var versus let is why in Swift there are no mutable and non-mutable versions of collections like Objective C’s NSArray and NSMutableArray.
when you passed around your structs its copied but when you passed or assigned classes it gets reference to it.This means when you change class object in one location it changes everywhere, when you affect structs it changes individually. if you want more information differences between classes and structs you can check araound my article.
classes versus structs

How to link two Realm objects

I'm new to iOS development and currently using Realm as database. My first tableview display Restaurant object and second table display customer objects. How can i link this two objects?. Means when i click each restaurant it will display different customer.
class Restaurant: Object {
dynamic var restname: String = ""
dynamic var date: String = ""
}
class Customer: Object {
dynamic var id = 0
dynamic var name: String = ""
dynamic var price: Float = 0.0
dynamic var drinks: Float = 0.0
override static func primaryKey() -> String? {
return "id"
}
}
You make references to your models like so
class Customer: Object {
dynamic var restaurant: Restaurant?
}
You also have the possibility to get reverse relationship with LinkingObjects(fromType:, property:)
You can write in your other model
class Restaurant: Object {
let customers = LinkingObjects(fromType: Customer.self, property: "restaurant")
}
That way you don't duplicate relationships.
If I understand, in Restaurant class put this:
dynamic var _customer = Optional(Customer())
or in Customer class put this line:
dynamic var _restaurant = Optional(Restaurant())
NOTE: Name of variable with lower dash, may be any name, my habit is to put lower dash

Converting Array of Objects into Object of arrays

I have a class with some arrays of different types and let's say they're all filled with the same amount.
public class CoreLocationMap {
var type: [String] = []
var location: [Int] = []
var groupName: [NSString] = []
var x: [Float] = []
init() {}
}
I want something like a JSON Object:
var jsonObject = ({type = myString; location = 123; groupName = anotherString; x = 0.123}, {type = myString; location = 123; groupName = anotherString; x = 0.123}, ...)
It's not necessarily to have a jsonObject, but i want to capsule my variables in logical groups, so
type
location
groupName
x
should make a struct/object/whateever^^.
If I use later for example a certain location i want to reference to the other variables in this group.
I'm also pleased about other solutions. If you need more details please tell me.
Thanks!
as you suggested you can use a struct to encapsulate your data:
struct LocationData {
var type: String
var location: Int
var groupName: String
var x: Float
}
and declare an array in your class :
var locationsData = Array<LocationData>()
add a function for adding elements :
func addLocationData(type: String, location: Int, groupName: String, x:Float) {
// Add additional safety/limitation checks
locationsData.append(LocationData(type: type, location: location, groupName: groupName, x: x) // structs have an implicit init method
}
you can create model calss lets say locationModel
like
calss locationModel{
var type:String
var location : Int
var groupName : String
var x: Float
// you can create Init method to init() model properties
// you can create custom method to fill values of model calss
/* you create custom method that accept array as argument create
this class (locationModel) type of object in function load data
from array to modelobject add modelobject in array and return
this array.*/
}
now you can create this model class object where you want to use and fill them with model class methods.
like if you want to use this in CoreLocationMap create location model and init it in your class and fill value.
and add this model objects in newly created array if you want array of object. hope this help you.
This library does the same thing for you JSONModel https://github.com/icanzilb/JSONModel
This library has the following method
NSArray* jsonObjects = [YourModelClass arrayOfDictionariesFromModels: modelObjects];
this method returns the Array of Dictionaries from Array of Objects.
Now , you can use
NSJSONSerialization

Get object type from empty Swift Array

Is there a way to get instance of Array element from the empty array? (I need dynamic properties because I use some KVC methods on NSObject)
import Foundation
class BaseClass: NSObject {
func myFunction() {
doWork()
}
}
class Car: BaseClass {
dynamic var id: Int = 0
}
class Bus: BaseClass {
dynamic var seats: Int = 0
}
var cars = Array<Car>()
What I need is a vay to get instance of empty Car object from this empty array, for example like this:
var carFromArray = cars.instanceObject() // will return empty Car object
I know that I can use:
var object = Array<Car>.Element()
but this doesn't work for me since I get array from function parameter and I don't know it's element class.
I have tried to write my own type that will do this, and it works, but then I cannot mark it as dynamic since it cannot be represented in Objective C. I tried to write extension of Array
extension Array {
func instanceObject<T: BaseClass>() -> T? {
return T()
}
}
but when I use it, it sometimes throws error fatal error: NSArray element failed to match the Swift Array Element type
Swift 3: Get an empty array's element type:
let cars = [Car]() // []
let arrayType = type(of: cars) // Array<Car>.Type
let carType = arrayType.Element.self // Car.Type
String(describing: carType) // "Car"
This seems to work as of Swift 2.0:
let nsobjectype = cars.dynamicType.Element()
let newCar = nsobjectype.dynamicType.init()
Not sure if it will work in earlier versions.
Something like this?
let cars = Array<Car>()
let car = cars.dynamicType.Element()

Resources