Save array of images with Realm in swift - ios

okay, i have an app with 3 view controllers and in 2 of them i have 5 arrays of images. what i want to do is save each array of images using realm. the arrays are mutable and the user adds the images to the array of their choosing in vc1 and can send them to the arrays in vc2, but im not sure if i can just replace (in vc1)
this:
var array: [UIImage] = [] {
didSet{
cView1.reloadData()
}
}
with This:
dynamic var array: [UIImage] = [] {
didSet{
cView1.reloadData()
}
}
i am also getting this error when i try to inherit RLMObject.
"multiple inheritance from classes uiviewcontroller and RLMObject"
here is my code
class CViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UICollectionViewDelegate, UICollectionViewDataSource, CDelegate , RLMObject
im fairly new to ios developing so any little bit helps thanks in advance

The best approach is to save file path in DB, not image itself. So you need to create array of image paths instead array of images. Like this: let images = List<String>()
Also according to Realm Docs 'List' can't be dynamic:
When added as a property on Object models, the property must be declared as let and cannot be dynamic.
And final, you must to inherit from 'Object', not 'RLMObject' and Realm class must be separate, like in this official example:
class Dog: Object {
dynamic var name: String = ""
dynamic var adopted: Bool = false
let siblings = List<Dog>()
}

Related

Array Data Through Different View Controllers Swift

Hey guys I'm working on my first ever app and need some help. My workout tracker app has two classes which you can find below. I have two view controllers hooked up to their own swift files.
Heres my first view controller
Basically what it does is takes the data in the text fields and steppers and turns it into a "Workout" object then appends it to the "WorkoutList" class array.
I've got a print statement setup that prints the Array.count. It shows the correct number in the debug but when I switch views it gets reset to zero.
#IBAction func addToWorkoutList(_ sender: UIButton) {
let workout = Workout(name: workoutName.text!, description: workoutDescription.text!, sets: Int(setStepper.text!)!, reps: Int(repStepper.text!)!)
workoutArrayList.append(workout)
print(workoutArrayList.count)
}
The second view inherits the first views class so that is how I access the "WorkoutArrayList"
class OverViewViewController: NewWorkoutViewController, UITableViewDelegate, UITableViewDataSource {
My app basically allows you to add a workout then produces a graph based on the data you provided. This can make it easy to visualize your gains in the gym. I'm doing this as a learning project so any help on what I should do to build this app would also be greatly appreciated.
Workout Object Class
import Foundation
class Workout {
let workoutName : String
let workoutDescription : String
let numberOfSets : Int
let numberOfReps : Int
init(name : String, description : String, sets : Int, reps : Int) {
workoutName = name
workoutDescription = description
numberOfSets = sets
numberOfReps = reps
}
}
WorkoutList Class
import Foundation
class WorkoutList {
let workoutArray : [Workout] = []
}
Inheriting the class is not what you want to do here. An easy fix for you would be to make workoutArray a static variable so any class can access it at any given time.
static var workoutArray : [Workout] = []
Here is why just inheriting the class doesn't work. When the OverViewViewController loads in to the app, it creates a new instance of the class OverViewViewController and since it inherits NewWorkoutViewController, it also creates a new instance of the NewWorkoutViewController class. You have 2 different instances of NewWorkoutViewController, changing a variable in one of those instances won't change it for any other instances of the class. A static variable, however, is what you are looking for. The array can be changed and accessed any time from any class, you don't even need to inherit. It would work whether you made workoutArray static or workoutArrayList static.
If you have any other questions, feel free to leave a comment.

Save EVObjects with CoreData

I need to save some data with CoreData. Generally thats not a problem at all. The problem is, that the data is created with EVReflection an therefore inherits the class EVObject. To save the gathered data to CoreData they have to also inherit NSManagedObject. The problem is that swift does not allow you to inherit multiple classes. Would appreciate any tips.
class Device : EVObject
{
var channel : [Channel] = [Channel]()
var name : String = ""
var ise_id : Int = 0
var unreach : Bool = false
var sticky_unreach : Bool = false
var config_pending : Bool = false
override internal func propertyMapping() -> [(String?, String?)] {
return [("name", "_name"), ("ise_id", "_ise_id"), ("unreach", "_unreach"), ("sticky_unreach", "_sticky_unreach"), ("config_pending", "_config_pending")]
}
}
You don't have to inherit. You can extend them. Example:
class User : NSManagedObject{
#NSManaged .....
}
//Extension
import EVReflection
extension User : EVReflectable { }
https://github.com/evermeer/EVReflection#extending-existing-objects
Note I'm not aware of EVReflection but I think this answer can generally apply.
Don't use multiple inheritance. Have two separate classes and a mechanism for creating/loading/updating one object from the other. Protocols may allow it to be done in a way that minimises translation boilerplate (possibly using valueForKey(_:) and setValue(_:forKey) if you can know the key names in a safe manner.
It may not even be even be necessary to have an NSManagedObject subclass but just have an instance of NSManagedObject in all your classes that is loaded/created/saved as necessary.
It depends on what functionality you want to use from EVReflection. Since NSManagedObject also has NSObject as it's base class you could use most functions by just setting NSManagedObject as your base class instead of EVObject.
The only thing you have to do is instead of calling EVObject functions directly, you have to implement the code snippets that are in that EVObject method. Almost any function there is just a convenience method that will call the corresponding EVReflection function.
If you have any questions in the future, then please also report this as an issue on GitHub.

Swift: Array not mutating between classes?

I'm working on a swift project where I create a custom keyboard. In my ViewController, I store and mutate an array of UIImages. Then, in my Keyboard module in my keyboardViewcontroller.swift I would like to use the data I have in this array to create buttons. However, when I try to access the array in KeyBoardViewController it seems to give me an empty array and throws an index out of bounds error. What is strange to me is that in ViewController I print out the size of my array and it is definitely not empty. Here is how I'm storing the array:
import UIKit
class Main {
var pics :[UIImage]
init(pics : [UIImage]) {
self.pics = [UIImage]()
}
}
var instance = Main(pics: [UIImage]())
In ViewController I mutate it with instance.pics.append...
In my KeyboardViewController:
for image in instance.pics {
...
}
Why would this show as an empty array in KeyboardViewController?
Thanks
Rather than assigning an empty array of UIImage objects, the following will set the internal array variable to be a copy of the myPics array.
import UIKit
class Main {
var pics: [UIImage]
init(pics: [UIImage]) {
self.pics = pics
}
}
var instance = Main(pics: myPics)

How to Properly Declare Array of Custom Objects in Swift?

Here is my custom class...not sure if I'm missing anything in it...
import UIKit
class baseMakeUp {
var Image = UIImage()
var Brand: String
var Color: String
var Rating: Int = 0
init (Brand: String, Color: String) {
self.Brand = Brand
self.Color = Color
}
}
I'm trying to instantiate here...
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
let cellIdentifier = "cellIdentifier"
var foundation: [[baseMakeUp]]
var blush: [[baseMakeUp]]
var eyes: [[baseMakeUp]]
var lips: [[baseMakeUp]]
var nails: [[baseMakeUp]]
// put some test data in makeup arrays here...
foundation[0].Brand = "Revlon" -------------> "Expected declaration" error.
foundation[0].Color = "Red"
foundation[0].Rating = 3
foundation[1].Brand = "MAC"
foundation[1].Color = "Blue"
foundation[1].Rating = 4
I didn't include the rest of the ViewController class, because I didn't think it was necessary.
The error occurs when I attempt to assign a value to foundation[0].Brand
Appreciate your help in advance!
First, I'm going to assume you didn't want 2d arrays. If you did, I'll answer your question from that perspective below.
var foundation = [baseMakeUp]()
Creates an empty array of baseMakeUp called foundation. You can't use subscripting to add elements to an array, you can only use it to change existing elements. Since your array is empty you add elements with append.
foundation.append(baseMakeUp(Brand: "Brand", Color: "Color"))
Since you don't have a baseMakeUp initializer that allows you to pass a rating that element's rating is 0. However since you appended it to your array you can now use subscripting to change it's Rating variable like this:
foundation[0].Rating = 3
If you did intend for 2d arrays.
var foundation = [[baseMakeUp]]()
To create the array
foundation.append([])
foundation[0].append(baseMakeUp(Brand: "Brand", Color: "Color"))
foundation[0][0].Rating = 3
The first line appends an empty array to your top level array. The second line appends a baseMakeUp to the array added in the first line. The third line uses subscripting to change the Rating of the first element in the first array of your 2d array.
Hopefully that helps with your problem.
Additionally
I was going to add points 1 and 2 from jday001s answer here, but you should check out their answer as well.
Edit
I just realized that you're trying to add elements to your arrays in the wrong scope.
You'll have to move your
foundation.append(baseMakeUp(Brand: "Brand", Color: "Color")
inside a function and call it yourself or place them inside something like viewDidLoad
eg:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var foundation = [baseMakeUp]()
override func viewDidLoad() {
super.viewDidLoad()
foundation.append(baseMakeUp(Brand: "Brand", Color: "Color")
foundation[0].Rating = 3
}
}
Hopefully that's helpful.
You have a few things going on here:
You are missing some naming conventions. Class names should be capitalized (baseMakeUp should be BaseMakeUp).
Class vars should be lower case (image, brand, color, rating). Also brand & color in the init method.
Do you intend for your foundation array to be multidimensional? If you just want a regular array, I'd go with something like:
var foundation = [BaseMakeup]?
As the other answer says, you also need to instantiate BaseMakeup objects using your init method:
let aBaseMakeup = BaseMakeup(brand: "Revlon", color: "Red")
After that, you can add BaseMakeup objects to your array like this:
foundation?.append(aBaseMakeup)
Hopefully I'm understanding what you are trying to accomplish.
First Create a custom class...
import Foundation
class ClassName{
var id: Int?
var name: String?
var category_name: String?
var price: Double?
init(json: JSON) {
self.id = json["id"].int
self.name = json["name"].string
self.category_name = json["category_name"].string
self.price = json["price"].double
}
}
Use can use this Class in viewcontroller by following lines
var arrayName:Array<yourclassname> = Array()
print("/(yourclaseename[0].name)")
You need to instantiate your class object
example:
var foundation = baseMakeUp(Brand: "Some Brand", Color: "Red")

Swift superclass/subclass view controller variables

I have a superclass UIViewController that contains this:
var results: [AnyObject] = []
I also have other methods in the superclass that's based on the content of results array.
I then have subclasses that inherit from this superclass, by loading data from REST API to populate results array with various types of data.
I currently don't override results array in subclass' viewDidLoad() or any other method. I simply clear the array using results = [] and then load the array with a specific class type, such as a custom class Product or String.
results.append(Product())
I've been intermittenly getting crashes, but I can't tell why. I suspect it's due to the way the inheritance is working. Am I doing this correctly? Should I be overriding results in an init() method of the subclass or using `override var?
I think typecasting can work here.
Try to do this in your subclasses:
class SubClass: SuperClass {
private var _results: [Product] = []
override var results: [AnyObject] {
get {
return _results
}
set {
_results = newValue as! [Product]
}
}
}
But Product must be a class and not struct or enum.
Also as String does not conform to AnyObject you cannot save Strings in results array.

Resources