Swift3: Using Two Arrays to populate grouped Table - ios

I currently have two populated arrays using a custom struct.
struct Group {
var id: String
var type: String
var desc: String
var name: String
init() {
id = ""
type = ""
desc = ""
name = ""
}
}
Data gets appended to:
var clientArray: [Group] = []
var departmentArray: [Group] = []
I essentially want to join them together to have the format something like [[clientArray], [departmentArray]] so I can use "section" and populate two different groups on a table with the respective arrays.
So far I've tried the following, but I get the error "fatal error: index out of range".
var masterArray = [[Group]]()
//Then further down the page...
self.masterArray[0] = self.clientArray
self.masterArray[1] = self.departmentArray
How can I get this to work? Thanks for any help.

You could write:
var masterArray = [self.clientArray, self.departmentArray]
Otherwise use append:. The docs state:
You can’t use subscript syntax to append a new item to the end of an
array.

Related

How to add optional values to an array in Swift

I'm having issues with appending an optional value to an array in Swift. The view I'm writing is for the creation of a routine for the gym. However my Routine object is not being instantiated as it should be.
I have experience with other programming languages but I am fairly new to Swift, and optionals.
My ViewController contains an optional variable:
var routine: Routine?
Where the Routine class contains:
name: String
exerciseList: [String]()
numOfSets: [Int]()
When I am preparing it to send the newly created routine to my other ViewController, I take the values from user input to edit the fields of the object.
let name = routineName.text ?? ""
let numberOne = Int(numOfSetsOne.text ?? "0") //numOfSetsOne is a text label
routine?.exerciseList.append(selectedExerciseOne!) //Haven't tested to see if this works yet
routine?.numOfSets[0] = numberOne! //This line is not working
routine = Routine(name: name)
To try a little debugging I put print statements on either side of the line like so:
print ("numberOne Value: \(numberOne!)")
routine?.numOfSets[0] = numberOne!
print ("numOfSets[0] Value: \(routine?.numOfSets[0])")
I expected the output from the second print statement to be identical to the first. However the terminal output:
numberOne Value: 3
numOfSets[0] Value: nil
Does anyone know what has gone wrong here?
Thanks
You have declared a property that may contain a Routine, but you have not assigned an instance of Routine to that property before trying to use it.
This means that, for example,
routine?.numSets[0] = numberOne!
doesn't do anything - routine is nil and so the statement is skipped.
You should create an appropriate init function for your Routine class and use that to create a new Routine and assign it to routine
For example:
class Routine {
var name: String
var exerciseList = [String]()
var numberOfSets = [Int]()
init(named: String) {
self.name = named
}
}
Then you can say
let name = routineName.text ?? ""
let numberOne = Int(numOfSetsOne.text ?? "0")
self.routine = Routine(named: name)
self.routine?.numberOfSets.append(numberOne!)
Coordinating related arrays can get a bit messy, so I would use a single array:
struct ExerciseSet {
let exerciseName: String
let sets: Int
}
class Routine {
var name: String
var exerciseList = [ExerciseSet]()
init(named: String) {
self.name = named
}
}
Your Routine is not initialised before its being assigned value
try
let name = routineName.text ?? ""
let numberOne = Int(numOfSetsOne.text ?? "0")
routine = Routine(name: name)
routine?.exerciseList.append(selectedExerciseOne!)
routine?.numOfSets[0] = numberOne!

Realm list property not saving data

I have two models, lets call them Schools, and Teachers. Models are as under
#objcMembers public class Schools : Object {
dynamic var Id : String = ""
dynamic var UserId : Int64 = 0
dynamic var Name : String? = ""
dynamic var listTeachers : List<Teachers>? = nil
dynamic var teachersList : [Teachers]? = []
}
#objcMembers public class Teachers : Object {
dynamic var Id : String = ""
dynamic var UserId : Int64 = 0
dynamic var Name : String? = ""
}
now before saving data I m putting Teachers objects (list) in School object then I save that School object in realm write closure.
after that I just get the School realm object and when I get the Teachers list, it always gets Nil. What is the case?
Am i missing something or missing something to understand the real LIST property??
please help
Update: This is how I am getting object
let mSavedItems = mDbHelper.realmObj.objects(Schools.self)
if let teachers = mSavedItems[0].teachersList{// here teacher list is nil
}
Your Schools declaration is flawed. You shouldn't declare a List as dynamic or mutable, nor should you make it Optional. As the docs clearly state, let listTeachers = List<Teachers>() is the correct way to declare a many-to-many relationship.
Storing a property of type Array is also not supported by Realm, so you should delete the teachersList : [Teachers]? property.
#objcMembers public class Schools : Object {
dynamic var Id : String = ""
dynamic var UserId : Int64 = 0
dynamic var Name : String? = ""
let listTeachers = List<Teachers>()
}

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

How to search an Array containing struct elements in Swift?

It's kind pretty straight forward to find an element in an array with type String, Int, etc.
var States = ["CA", "FL", "MI"]
var filteredStates = States.filter {$0 == "FL"} // returns false, true, false
Now, I created a struct
struct Candy{
let name:String
}
and then initialized it
var candies = [Candy(name: "Chocolate"),
Candy(name: "Lollipop"),
Candy(name: "Caramel")]
Can anyone please suggest the right way to find "Chocolate" in the array containing struct elements? I'm not able to implement the find or filter method.
With the following code you receive all candy structs in the array, which match to "Chocolate".
var candiesFiltered = candies.filter{$0.name == "Chocolate"}
If you just want a boolean if it has been found or not you could use the following code:
var found = candies.filter{$0.name == "Chocolate"}.count > 0

Resources