I want to make a class that can hold settings for my app. Its pretty basic. I will access it from a few different classes, but only want 1 version of this container class to exist so they all see the same data.
Is there something special i need to flag for this?
Here is what I've done so far:
Filters.h
#import <Foundation/Foundation.h>
#interface Filters : NSObject
{
NSString *fuelType;
}
#property (nonatomic, copy) NSString *fuelType;
#end
Filters.m
#import "Filters.h"
#implementation Filters
#synthesize fuelType;
#end
Is there some flag i need to use when i alloc an instance of this class or how should I work this if I need to access the fuelType value from 2 different classes?
Thanks
-Code
For global application settings a better way would be to use NSUserDefaults or if you want to store data for use you should look up using core data and sqlite.
Lastly, if you want to go for ease of use you could do a core data style app delegate class and grab it by using:
[[[UIApplication sharedApplication] delegate] myClass] that way you'll always have that version of the class.
You need a singleton:
you can create your singleton by your own or use AppDelegate object which is an object that is always alive and never released while your application in the frontground (just put the vars needed there and initialize them dynamically).
Here are some links on how to create a singleton.
Cocoa fundamental Guide: Creating a Singleton
and
CocoaDev Singleton Pattern
What you're looking for is a singleton. Most people advise against using singletons though as it is often considered "dirty". See "Singleton" in this apple doc to learn more about it.
Related
Hello and thanks for any help in advance. I tried searching but it seems that what I am trying to do is no common. If there is another post talking about my question please link.
To get started, I have two classes. To keep names simple, one is called Controller and the other is my AppDelegate. The controller is a static library. The AppDelegate creates an instance of the controller using the following.
*Note: I have already declared _controller in .h file.
_controller = [[Controller alloc] initWithAppDelegate:self];
What I would like to do, is call methods in the AppDelegate class from the controller. Relevant code in the controller.h class is as follows.
#interface
{
id _appDelegate;
}
-(id) initWithAppDelegate:(id)appDelegate;
and in controller.m
-(void)someMethodName
{
[_appDelegate method];
}
The issue I am having is that method is not available to be called. I can call several other methods but not the custom methods I have created within AppDelegate. I have tried replacing ID with the AppDelegate but I can't seem to be able to import AppDelegate, I somewhat understand why I can't import it.
The reason I am creating my project this way is that I would like to reuse the controller code in applications that have a UI designed for different devices. If any of this is unclear or you need more information, feel free to ask.
Thanks.
Declare a protocol like this in your static library:
#protocol AppDelegateRequiredMethods
#required
... methods here ...
#end
Then, import the header that declares that protocol into your various AppDelegate implementations and declare your app delegate as implementing said protocol:
#interface MyAppDelegate:NSObject <AppDelegateRequiredMethods>
...
#end
The Controller has no knowledge of the app delegate or its methods. You must declare the interface using a protocol.
#protocol AppDelegateMethods
- (void)method;
#end
//Then replace your current id with
id <AppDelegateMethods>
we are a group working on an iPhone app. and its our first time. I just would like to know the easy way to implement a public class so that my partner can give me a variable that contains a value i need to use in my code. It doesn't have to be a class any other easy solution would work.
Just to make it more clear my friend has a value in his code that i need to use to display it on the screen "using my code". What i know is that everything has to communicate through a controller class which in this case the thing i need to implement my friend must be able to call it, give it the value then i take this value and display it. THANK YOU IN ADVANCE!
I. Just make an property in .h
#property (nonatomic, retain) NSString *userName;
and in .m file
#synthesize userName;
Docs here
II. He can make and delegate protocol in his class, the you need to set your object to be the delegate of his class instance and implement the delegate method. When he has the vale will call the delegate method and you will recive it in your method.
Docs here
In regards to XCode templates with CoreData enabled, I've read unclear use of #property in window app using core data which goes over the 'what' in the templates. But I am having an issue with the 'why'. By declaring the category in the implementation file, the CoreData accessors act like private methods. The problem with that is whenever you want to use CoreData elsewhere in your app, you need some extra code.
I've figured you need to either supply your own method that exposes the managed object context, such as...
- (NSManagedObjectContext *)getManagedObjectContext
{
return self.managedObjectContext;
}
...which will allow other parts of your app to use it.
Or you would need to jam pack your app delegate with specific methods to return managed objects, ie getProducts or setUser.
Can anyone shed light on the reasoning here?
The reason for this is because you should be using dependency injection in your designs. This is the recommended design by the Core Data team. What is expected is that your app delegate will set the NSManagedObjectContext reference in your root view controller(s). From there the controllers will set or inject the necessary dependencies in the following view controllers.
This will lead to a more flexible design. I discussed it in depth in my article on the MDN (http://www.mac-developer-network.com/articles/cd0004.html).
If your project is big and needs to access the managed object context from outside of the AppDelegate,
I would just move the property declaration of managedObjectContext to the header file, as in:
#interface myAppDelegate : NSObject <UIApplicationDelegate> {
NSManagedObjectModel *managedObjectModel;
NSManagedObjectContext *managedObjectContext;
NSPersistentStoreCoordinator *persistentStoreCoordinator;
}
#property (retain,nonatomic) NSManagedObjectContext*managedObjectContext;
#end
Then the other parts of the app can just use appDelegate.managedObjectContext.
There's no reason to expose managedObjectModel or persistentStoreCoordinator outside the app delegate, though.
By the way I have a few comments about your usage of Objective-C:
Don't use get in front of the getter. For a property called foo, the getter should be
-(Foo*)foo;
and the setter should be
-(void)setFoo:(Foo*)_foo;
By convention, get... is used when a pointer is fed as a method argument, as in -[NSString getCharacters:range:] (See the Apple doc).
Follow the proverb, when in Rome, do as the Romans do.
I am new to the iPhone development environment so be gentle:
Currently writing an iPhone game app that will also have a high score view. Was wanting to make this view so that it was on its own and I could call it from another class (.m file)
Question is, how do you call another class file? I know I need to include the header from that file, but how do I call a "function/message" from that class...something like updating the high score?
I hope this makes send. Thanks in advance for any and all help.
Geo...
You really should work your way through the introductory documentation on Apple's developer website:
Learning Objective-C: A Primer
and
Your First iPhone Application
If your function is static, call it like this:
[ClassName theFunction:parameter];
If your function is a member of the class, then create an instance of that class and call the function like this:
ClassName obj = [[ClassName alloc] init];
[obj theFunction:parameter];
Don't think of it as calling functions/methods/procedures/whatever. Think of it as one object talking to another. What do they need to do this? You need a reference to the object you want to talk to.
Often, you'll want to create an instance variable that gets assigned to the object you're interested in. If both objects are in a nib together, you can draw connections between them in Interface Builder. Otherwise, you'll need to structure your code so that they can find each other (e.g., give the nib's owner a reference to whatever other object needs to talk to the view).
You might want to try working through one of the many tutorials out there (for instance, on Apple's developer site) to get a feeling for how this works.
The preferred technique for this would be delegation. So that your main view delegates the task of scoring to your HighScore view.
#protocol myDelegate;
#interface myClass : UIView {
id <myDelegate> delegate;
}
#property (nonatomic, assign) id <myDelegate> delegate;
#end
#protocol myDelegate
- (void)myMethod //Method to be implemented by your High Score View
To implement this protocol in your High Score View do:
#interface HighScore : UIview <myDelegate>
The in your HighScore.m implement the method mymethod:
- (void)myMethod {
//update Score etc...
}
To call the method from your other view do:
myHighScoreView.delegate = self // self is your other view
[delegate myMethod] // calls the method in the other view.
I hope that's clear.
-Oscar
I'm new to Objective-C and development on Apple's platforms, but hopefully I can frame this question in an understandable way regardless :)
I want to parse an XML feed for my iPhone app, and I decided instead of shoving all of the delegation methods from an instance of NSXMLParser into my view controller, I'd wrap this up inside of a FeedParser class. After reading a few docs and example code, here's what I came up with:
#protocol FeedParserDelegate <NSObject>
- (void)parserDidLoadEpisodes:(NSArray *)episodes;
#end
#interface FeedParser : NSObject {
id <FeedParserDelegate> delegate;
}
#property (nonatomic, assign) id <FeedParserDelegate> delegate;
- (id)initWithURL:(NSURL *)url delegate:(id<FeedParserDelegate>)theDelegate;
#end
Simple. Delegates of my FeedParser object just have to implement parserDidLoadEpisodes.
However, as I started actually making my FeedParser class use NSXMLParser, I realized that I didn't have to specify that FeedParser implements a protocol for NSXMLParser -- I could just implement the delegate methods that I wanted to do something with. I think I've noticed this with other classes that follow the delegate pattern, too, but not all.
So why wouldn't I too just not bother with specifying a formal protocol for my FeedParser class? It would cut away some perhaps unnecessary code. I guess the question is: why would I want to create a formal protocol instead of just doing something like just checking to see if the method is implemented on the delegate with respondsToSelector? Is it only so that the compiler will issue nice warnings if a required delegate method isn't implemented?
A protocol declared with #protocol is called a "formal protocol". The other way to do it is to declare a category (a set of additional methods) on NSObject, like so:
#interface NSObject (FeedParserDelegate)
- (void)parserDidLoadEpisodes:(NSArray *)episodes;
#end
Then simply define that method for any object that you want to be a feed parser delegate, and leave it undefined otherwise. This is called an "informal protocol".
Why are there two ways? Well, here's a hint: the informal protocols came first. What it comes down to is that they added formal protocols because informal ones weren't cutting it. Informal protocols make it too easy to forget an important method or try to use an object as a delegate for something it's not designed to work with.
Basically, for the cost of adding <FeedParserDelegate> here and there, you can get the compiler to do your debugging for you. The compiler will generate warnings for the most common delegate bugs, which saves you time if you make one of those mistakes. Why not take advantage of its helpfulness?
Always, always, always favor compile-time error checking over run-time. You could of course ask the class if it supports the method, but why ask when you can know?
The answer is no, you don't have to. But you should want to. :)
Adding a protocol makes the compiler check things for you. If you don't get those nice errors at compile time, then you'll get them later at run time when they're harder to track down.