Writing an SDK in Objective-C - ios

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.

Related

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.

Create an instance of a class inside its own self

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
}

Realm Many to Many Query (Inverse too!)

My app's db has a many to many relationship between a Feed object and a Tweet object. This is to keep track of which feeds every tweet belongs in. If you're familiar with Twitter, imagine the main feed, a list feed, a user profile feed, etc.
How can I make a query using an NSPredicate to get a list of Tweets that exist in a specific Feed (and, inversely, get a list of Feeds that a Tweet exists in)? It seems that queries on inverse relationships does not work in Realm, so what are my options?
If I understand your question correctly this part of the documentation should be helpful:
Inverse Relationships Links are unidirectional. So if a to-many
property Person.dogs links to a Dog instance and a to-one property
Dog.owner links to Person, these links are independent from one
another. Appending a Dog to a Person instance’s dogs property, doesn’t
automatically set the dog’s owner property to this Person. Because
manually synchronizing pairs of relationships is error prone, complex
and duplicates information, Realm exposes an API to retrieve backlinks
described below.
With inverse relationships, you can obtain all objects linking to a
given object through a specific property. For example, calling
Object().linkingObjects(_:forProperty:) on a Dog instance will return
all objects of the specified class linking to the calling instance
with the specified property.
I guess you can do something like:
//assuming your Tweet object has a property like "let feeds = List<Feed>()"
someTweet.linkingObjects(Feed.self, forProperty: "feeds") //should return feeds your Tweet is in
But still I don't think I understand your question clearly. From my point of view your first requirement:
get a list of Tweets that exist in a specific Feed
should have a straightforward solution such as having a property in your Feed object like:
let tweets = List<Tweet>()
I wish you can clarify your situation further.
I wonder if it's possible to simplify the model a bit so many-to-many isn't necessary.
My understanding of Twitter is that tweets aren't 'owned' by any feeds. They simply exist on the platform, and are referenced by any number of feeds, but don't actually belong to any specific feed.
So a model setup like this should be appropriate:
class Tweet : Object {
}
class Feed : Object {
let tweets = List<Tweet>()
}
You can do a reverse lookup on a Tweet to see if there are any feeds in which it is currently visible, and you can simply use the tweets property of Feed objects to see which tweets they're displaying
Since the linkingObjects reverse lookup method of Realm simply returns a standard Swift Array, if you did want to filter that further, you could just use the system APIs (like filter or map) to refine it further.
Otherwise, if you really do want to be able to use Realm's NSPredicate filtering system both ways, then, as messy as it is, you would need to manually have each model linking to a list of the other:
class Tweet : Object {
let feeds = List<Feed>()
}
class Feed : Object {
let tweets = List<Tweet>()
}
While it's not recommended (Since it adds additional work), it's not disallowed.
Good luck!

Best alternative for 'long term' storing model-view-controller data in Objective-C/ios

I am planning on creating my app in a 'Model-View-Controller'(MVC)-style, and in the end, for me at least, this means that all data is stored in the controller-class. Let's say I have a class Player, and the player has several objects of class Weapons or Equipment or whatever. The initialization of Controller* stores the player(s), so if I can store/save only the Controller-object over time, even if the app or the device restarts, that would be nice. I did this in Java one, I put in Serialization = 100L;(or something like it) in the top of the file of every object that would be included when saving the Controller-object, and it worked perfectly. Is this possible in ios/cocoa-touch/objective-c?
I have read and used Core Data (not very much), but that is just a database-table, sql?, which would have me extract every piece of information of every object?
For instance, if the object Player* has a member NSString *name;, I would have to save the actual string in Core Data, instead of saving the object of the player? Like, varchar.
If there is any way to store an entire custom object on the device for further use, I would very much like to know what it's called, and where I can read about it/tutorials.
Read up on the NSCoding protocol. You can make your object complient to it, then serialized it and save it to a file. Later you can restore it to the same state by using a decoder. For sure some other posts that cover this topic on SO.

Unsure of how to manage data in ios app

I hope this question isn't too general/ambiguous...
I'm writing an iphone quiz game app and am having trouble figuring out the best way to handle data. Currently I am thinking of having a single Model class that holds an array of "User" classes which each have an array of user-specific "Question" classes. I'd like to be able to access the overarching Model from any of my view controllers, but that means I'll probably have to pass the model object to any new view controller, use a singleton, or do something else. What is the best way to access my Model object from other classes? Another factor I'm not sure about is being able to save the data - would I have to use Core Data/SQLite to save my single Model object, or is there a simpler way?
I'd start by designing a schema using CoreData. IMO, its best to start out using CoreData because then you'll never have to convert your data layer to CoreData, in the event that your app scales beyond a simple object or two.
The other route would be to create a web service that returns your data... so you just call the service and it returns a collection of user objects. You can either send down the entire object graph with the questions, or create another service to return a collection of questions for a specific user. If you have a web server handy, this method scales the best because you don't have to rely on app updates to get new questions into your system. I would still use CoreData to cache the results... so that way you're not downloading the same information all the time.
So when it comes to accessing CoreData objects, I use a repository class that's a singleton. This makes it easy for any view controller to grab an instance of the repository and get some data. Here's what something like that might look like;
[[Repository defaultRepository] findFirst:[User class]
where:#"name == 'John'"]
There's a lot of redundant code to fetch data so wrapping that up in an object will help get all that nasty code, like predicates and sorting, out of your view controllers. You can see where I leverage a va_list in the where clause so I can inject that string right into my predicate. Here are some other methods you could implement:
- (NSArray *) findAll:(Class)entity
sortByKey:(NSString *)key
ascending:(BOOL)ascending;
- (NSArray *) findAll:(Class)entity
sortByKey:(NSString *)key
ascending:(BOOL)ascending
where:(NSString *)format, ...;
- (id) findFirst:(Class)entity
where:(NSString *)format, ...;
I'm not sure if this is the preferred way, but I've had a lot of success with this method. Hope this helps!
Check this link, this will help you a lot
Link: http://mobile.tutsplus.com/tutorials/iphone/iphone-sdk_store-data/
This cover 4 major ways to store data in iPhone with sample code.
1) NSUserDeafult
2) Property Lists
3) SQLLite
4) Core Data

Resources