Modal creating class object and setting values - ios

Hello this problem is more concerned with the programming problem rather then the specific language syntax. I am getting a nil user_id value after setting a value in class object. So I thing I am doing something wrong here
I have two classes. User and Trip
Trip.swift
class Trip: NSObject {
var tripID: Int?
var tripTitle: String?
var user:User?
var params: [String:NSObject] {
return [
"user_id": self.user!.userID!,
"trip_title": self.tripTitle!,
]
}
When I send these params to server I get a nil value user_id
var trip: Trip?
trip?.user?.userID = 9
I am not writing a whole code. I think I am doing something wrong in modal class or not setting the userID correctly. Please let me know if you can't figure out the problem from this info so I'll post full code here
class User: NSObject {
var userID: Int?
var email: String?
var password: String?
var firstName: String?
var lastName: String?
var params: [String:NSObject] {
return [
"email": self.email!,
"password": self.password!,
"first_name": self.firstName!,
"last_name": self.lastName!,
]
}

If all the data in both classes is always mandatory in real life, then
you should not designate those properties as optional.
This will force you to write proper initialisers and then
you will be forced to populate each object with correct values, which in turn
will lead to abandoning the need for force-unwrapping just before you send to server.
Following these steps will fix your problem.
Bonus advice: You don't have to inherit from NSObject. Do not inherit from anything. Everything here is possible to do with swift standard library. The dictionary then will use AnyObject as value.

Related

Model Object Issue

I am trying to create a model object to store json data received from newsAPI. However one of the keys called description matched a reserved keyword in swift. How do I resolve this ? The error message read Error Message: Property 'description' with type 'String?' cannot override a property with type 'String'
class ArticlesData: NSObject {
var author: String?
var title: String?
var description: String?
var publishedAt: String?
var urlImage: String?
var urlWebsite : String?
}
author : Andrew Marino
title : Vergecast: this week’s Section 230 hearing and the season of weird gadgets
description : Nilay, Dieter, and Adi discuss the latest Section 230 congressional hearing featuring the CEOs of Big Tech. Ashley Carman stops by to talk about how gadget makers are turning to shopping channels to market their products.
url : https://www.theverge.com/2020/10/30/21541796/section-230-hearing-gadgets-qvc-razr-2020-review-vergecast-podcast-428
urlToImage : https://cdn.vox-cdn.com/thumbor/sgk9rqbUKhLVhNxKunmuX_Zm6TM=/0x146:2040x1214/fit-in/1200x630/cdn.vox-cdn.com/uploads/chorus_asset/file/19749210/vpavic_200214_3909_samsung_galaxy_Z_flip_0013.jpg
publishedAt : 2020-10-30T14:44:14Z
content : Photo by Vjeran Pavic / The Verge\n\n This week on The Verge’s flagship podcast, The Vergecast: Sen. Ted Cruz (R-TX) yells at Twitter CEO Jack Dorsey, gadget makers are going to QVC, and it is weird ph… [+3098 chars]
Simplest solution: Use a struct, neither a class or even a subclass of NSObject is necessary.
struct ArticlesData {
Otherwise just use a different name.
If you are going to decode the JSON with Decodable add CodingKeys to map the dictionary key to the struct member with a different name.
And don't declare all properties carelessly as optional. Declare only those as optional which can be nil.
I've run into the same 'issue' several times and it's quite annoying indeed. You should rename your property to something else.
How are you mapping your JSON into the object? If you use Codable, you can use custom CodingKeys such as:
class ArticlesData: NSObject, Codable
{
var author: String?
var title: String?
var myDescription: String?
var publishedAt: String?
var urlImage: String?
var urlWebsite: String?
private enum CodingKeys: String, CodingKey
{
case author, title, myDescription = "description", publishedAt, urlImage = "urlToImage", urlWebsite = "url"
}
}
EDIT: As vadian said, you can also use a struct. I actually prefer that solution over renaming the propery to another name than you want.

Missing argument for parameter when creating Swift Realm Object

I am creating a simple User object that inherits from RealmSwift's Object:
import Foundation
import RealmSwift
class User: Object {
#objc dynamic var userId: String = ""
#objc dynamic var email: String = ""
convenience init(userId: String, email: String) {
self.init()
self.userId = userId
self.email = email
}
When building, I receive the following error Missing argument for parameter 'userId' in call.
Am I missing something here?
Why use a convenience initializer? You can initialize Users with Realm's default initializer,
let user = User(value: ["userID": "1234", "email": "email#gmail.com"])
As it stands, you haven't written an initializer which accepts 0 arguments, but you are currently calling it...
You can remove the word "convenience", and change the line:
self.init()
to
super.init()
and the error will go away, and the object will be properly initialized.
This is because the superclass Object does have an initializer which takes no arguments.

Swift. Refer to instance variables by string name

I've got a number of user properties in a user viewcontroller class ie
//user vars
var email: String?
var givenName: String?
var familyName:String?
var phone: String?
var dob: NSDate?
In a method within that class i retrieve user data from coredata and set the user text fields with that data in a loop
for i in 0 ..< userTextFields.count {
let field = userTextFields[i]
let fieldName = userTextFieldKeyNames[i]
let fieldText = currentUser.valueForKey(fieldName) as? String
field.text = fieldText
}
the fieldName variable in the loop matches the class's ivars above. Is there a way i can reference the ivars within the loop by matching it with the fieldName string so I can set the values of the ivars with the fetched coredata values ie in a literal sense saying something like the following ...
if self.property.name.text == fieldName {
self.property.value == fieldText
}
ie somehow resolving the various property names withing the class ... or is this bad design? .... if so any suggestions on achieving the same result in a better way
Not Swift-ish, as it's bypassing compile time type checking. Best option is to keep them all in a dictionary, and use a protocol to define allowed data types in the dictionary, but even that is rather poor

Set relationship between Model classes

Hello I need to know what would be the standard way to implement this kind a functionality.I'll explain first the whole scenario
I have two Model classes User and Trips
class User: NSObject {
var email: String?
var password: String?
var firstName: String?
var lastName: String?
}
class Trip: NSObject {
var tripTitle: String?
var tripSummary: String?
var departureCountry: String?
var destinationCountry: String?
}
Now in the database I use join query in trips and User table when I fetch results in Trips Controller because I have to get the user information as well like his name
My Program is like this I get each variables from the backend and set them in trip Class object and then pass this object through segue. Now the problem here comes when I have to set the userinformation as well which I get in the same array. I know I have to create user object if I have to set these variables as well but how can I pass two objects through segue or should I have to to do some changing in the trips Model Class?
Is there any standard or proper way to handle this kind a situation ?
You can declare the object of User class inside the Trip class.
class Trip : NSObject
{
var userInfo : User?
var tripTitle : String?
var tripSummary : String?
var departureCountry : String?
var destinationCountry : String?
}
Then you can set the data like:
let trip = Trip() // Initialise trip
trip.userInfo = User() // Initialise user
trip.userInfo!.firstName = "Midhun"
trip.userInfo!.lastName = "MP"

Swift: model structs, using optionals vs initialization of empty values

In Swift, say for example I have a struct for this model:
struct Message {
var message: String = ""
var timestamp: String = ""
var id: String = ""
}
And I would be instantiating multiple Messages using this struct from a database, and then populate a TableView with them.
Would it be best practice to using optionals instead of setting these variables with empty strings like such?
struct Message {
var message: String?
var timestamp: String?
var id: String?
}
Would it be more efficient to basically setting the variables to nil vs an empty string? Does nil take less memory vs empty string?
Before thinking about optimization, you have to ask yourself the good question: is there any chance that Message may contain optionals for one or several of its properties? If yes, use optionals, if no, don't use optionals.
Then, if you want to improve your code, you can use memberwise initializer for your struct:
struct Message {
var message: String
var timestamp: String?
var id: String
}
let message = Message(message: "Some message", timestamp: nil, id: "Id14")
Finally, I doubt any memory optimization on Struct (with optional or non optional properties) will give any significant improvement to your app/project.
Avoid optionals whenever it is possible. Stored properties are not as magical as they are in objective-c. Just give them default values if it is appropriate.

Resources