Create an instance of a class inside its own self - ios

Here's the situation.
I have a swift model class file that contains all the variables for a weather forecast (min temperature, max temperature, humidity, etc).
The class also contains the function that downloads all the data from the API.
My question is, is it possible to create an array of the class inside the class itself, so that I can append a number of objects (of the same class itself) based on the number of days of forecast the API sends back?
If so, can you tell me how it could be achieved?
The other option I have that totally works, is to do the API downloading and parsing outside of the forecast class (in the ViewController) but that would make my ViewController messy.

You shouldn't call the API to get all the weather's datas in your model but in a dedicated class.
Also, you shouldn't parse and store the datas inside your model.
In your model, you only need to have all the attributes of your object and methods.
Maybe you can create an Helper class where you implements all this methods and store the datas.

There's nothing preventing you from referencing a class name within its definition. So you can do something like this:
class Foo {
var boz = [Foo]() // you can append to this array as needed
}

Related

Value type design pattern to replace class

We are a looking for a value type design pattern in swift that will allow us to create a shopping cart to hold Products. We are currently using a class but that is a reference type and when we try to add two different version of the same product (i.e. with a different colors or sizes), the first item we added gets changed to the second item we added because it points to the same object in memory.
The design pattern needs to be “global” so we can access it from any page in the app. Right now this is our Cart class that stores all the items in the cart. What do we need to do to make this a value type or how does it need to be reengineered to use a struct without a class?
class Cart : NSObject {
var allProductsInCart = [MainProduct]()
override init() {
super.init()
}
class var sharedCart: Cart {
struct Static {
static let instance = Cart()
}
return Static.instance
}
}
The problem we are getting is that we need the products in the cart to be of custom class “MainProduct.” Right now as you can see, they are stored as “MainProduct.” Do we need to switch the products to a struct or other design pattern as well? How would we do that?
Yes, given the desired behavior between a value type vs. reference type you should use a Struct.
A commonly used "pattern" for doing this is called "Redux".
The idea is that you have one, immutable version of the "state" of your app.
It can be accessed from anywhere and the only way to update it is through "actions". These will reconstruct the entire state with the required updates.
ViewControllers and views, etc... subscribe to updates of various parts of the state.
So you could have an AppState that contains a ShoppingCartState. When a product is added to it your CartViewController will be informed of this update and can update its view etc...
There are many different frameworks that are built to use Redux so I won't recommend one as you should find the one that is right for you. But I believe this pattern best suits the usage you are after.

How to iterate over the properties of my models in objective c?

I want to iterate over the properties of my models in Objective-C. I tried this. Created PropertyUtil class with method classPropsFor:(Class)klass. Please find the attachment. Used objc/runtime.h. The code which I got from the net. In my viewcontroller I am doing this. [PropertyUtil classPropsFor:[self.user class]];. self.user is User model class. What I want to know is how can i iterate over the properties of my models, let's username, password and those values.
You may want to manually list all properties your model has.
Just add a method to your model:
+(NSArray*) propList {
return #[#"prop1", #"prop2"];
}
Then just use key-value coding to get the value
[someObject valueForKey:#"prop1"];
That's pretty straight and simple way if you wish to avoid Obj-C meta functions. Since you add your properties manually anyway, you may also add them in your list as well.
That's of course, if you don't have a large amount of models already and you wish do them all at once.

This is a generic design pattern regarding accessing model object value

In iOS, I have three controllers A,B,C. I have a model object and I am storing text box value in model property of an object and then I am storing model object in database where all this things happening in controller A. In controller C, I am trying to access that model object property, it shows me nil. I don't know why. Below is the example:
I have a model.m class like below
#implementation model:NSObject
#property(nonatomic)NSString *firstname;
A.m class
model m=[model alloc]init];
m.firstname=#"stackoverflow";
// and saving the "m" in PARSE framework which internally stores in database.
C.m class
model m =[model alloc]init];
NSLog(#"%#",m.firstname);// shows null value
what is the right way to access it? Please help me in this case.
You should use a Single Instance

Managing an enum within a PFObject - iOS Swift/Parse

I'm new to Parse and Swift.
I have an app where people play against each other.
I want to create an activity feed where game results, cheers, heckles (anything really) can show up in a list.
My thought is to create an Activity class that subclasses PFObject and I'd like to have an enum ActivityType to determine what kind of Activity is being created.
Can I set up the Activity object in Parse and the PFObject in Swift so that each Activity is set up with the correct ActivityType?
My thinking is that I need a "Type" column in Parse that's just a number and an init method that reads that number and sets the correct type.
Does that sound about right?
Thanks
You could use a type column in parse, though I'd expect each of your different kinds of feed item to be different classes in parse as they all have different data and relationships, so you could use the class type (name).
In either case this is just a way to identify the type coming from the server. Once you have that you want an organised and common approach to displaying the feed items. To do that you should have a protocol which defines what a feed item needs to provide in order to be displayed on the feed. Then you have a set of classes, each conforming to that protocol, and each dealing with one of the different types of feed item to 'mutate' them into the common format for display.
Using an enum in your app would work, but it could lead you to have one big switch statement dealing with everything. So long as you just use the enum and switch to deal with deciding which class to create to handle the feed item then your code should be well structured.
I've solved this problem. It was 'free' functionality from Parse. I think first of all, you should consider subclassing PFObject (for many reasons). Once you do this, all you have to do is add the enum as a property to your subclass. It's taken care of automatically by Parse.
Parse knows how to convert to NSNumber and vice versa for an enum, no need to worry about that.
Note, in your .m file:
#implementation MyParseObjectSubclass
#dynamic aPropertyIWantPersisted; // declare your properties as dynamic to be managed by Parse
#synthesize aLocalTransientProperty; // if you have transient properties that you don't want persisted to the server.
+ (void)load
{
[self registerSubclass];
}
+ (NSString*)parseClassName
{
return "MySubclass";
}
#end

Writing an SDK in Objective-C

Basically, I want to make api calls using an SDK I am writing.
I have the following classes:
Car
CarData (stores input values needed to create a car like model, make, etc)
Basically to create a car I do the following:
[Car carWithData: cardata onSuccess: successHandler onError: errorHandler]
that basically is a factory method that creates instance of Car after making an API call request and populating the new Car class with the response and passes that instance to the successHandler.
So "Car" has the above static method to create that car, but also has non-static methods to edit, delete cars (which would make edit, delete API calls to the server)
So when the Car create static method passes a new car to the successHandler by doing the following:
successHandler([[Car alloc] initWithDictionary: dictionary)
The success handler can go ahead and use that new car to do the following:
[car update: cardata]
[car delete]
considering the new car object now has an ID for each car that it can pass to the update and delete API calls.
My questions:
Do I need a cardata object to store user inputs or can I store them in the car object that would also later store the response from all of the api calls?
How can I improve this model?
With regards to CarData, note that there might be different inputs for the different API calls. So create function might need to know model, make, etc, but find function might need to know the number of items to find, the limit, the start id, etc.
First, names are very important in building an SDK. Your names are a bit confusing. CarData sounds very much like it is related to an NSData. The typical name for "a class that holds information about another class" is a "descriptor." So, I would call this CarDescriptor. See UIFont and UIFontDescriptor for inspiration.
Next, your carWithData:onSuccess:onError: very much sounds like it should return a Car, but it appears to be void. I recommend the following:
+ (void)createCarWithDescriptor:(CarDescriptor *)descriptor
completion:(void (^)(Car *car, NSError *error))completion;
It is preferred to have a single completion block, rather than two. Do not prefix completion handlers with on.
The CarDescriptor class should help you with your searching question as well, but it should not include things like limits. You should wrap that in a CarSearchRequest (or possibly just a CarSearch). See NSFetchRequest for inspiration. Whether you pass a CarDescriptor or need a full predicate depends on how your service manages searches. (Of course, you could always have code that converts a CarDescriptor into a predicate.) Again, look at how UIFontDescriptor is used to search for fonts for inspiration.

Resources