How to decleare custom protocol in iPhone - iphone

I want to use a protocol, how can we implement it in iPhone.
///In POCViewController.h
#import
#protocol BasicAPI
-(NSString*)hello;
#end
#interface HessianPOCViewController : UIViewController
{
idbasicAPI;
}
#end
///
// In POCViewController.m
// In Some method
NSURL* url = [NSURL
URLWithString#"http://www.caucho.com/hessian/test/basic"];
id proxy =
(id)[CWHessianConnection
proxyWithURL:url
protocol:#protocol(basicAPI)];
NSLog(#"hello: %#", [proxy hello]);
////
Please help me how I can implement above code?

In the above code snippet - the #protocol block goes in your header file, underneath the #end declaration that's already there. Common use case is something like:
#interface MyClass
// properties, method definitions, etc
#end
#protocol BasicAPI
-(NSString*)hello;
#end
Then in some method body in your implementation file, MyClass.m
-(void)myMethod {
NSURL* url = [NSURL URLWithString#"http://www.caucho.com/hessian/test/basic"];
id proxy = (id)[CWHessianConnection proxyWithURL:url protocol:#protocol(basicAPI)];
NSLog(#"hello: %#", [proxy hello]);
}

I see that the example you give is taken from the documentation for the Hessian Objective-C implementation. It's showing you how to interact with a Hessian web service from an Objective-C client.
Do you have an existing Hessian web service that you're trying to talk to? If so, you need to declare in your #protocol block the interface to that service. The answers to this question give some good examples of how this works on both the client & server side.

Related

How do i keep my code organised when my app needs a helper class?

I have a few custom UIViewControllers in my app which need to know the string returned of an NSDate. I could copy and paste the same code between these classes, but that's obviously terrible practise. It's also probably not good to put it in 1 class as a method, then have another class add this class to take advantage of it's method. It seems like a messy thing to do. So what would you recommend i do?
To clarify - I need a method which is given an NSDate and returns a string, for use in several other classes.
Sounds like you either need a function, rather than a method:
//Helpers.h
#import <Foundation/Foundation.h>
NSString * makeAStringFromThisDateSomehow(NSDate * d);
//Helpers.m
#import "Helpers.h"
NSString * makeAStringFromThisDateSomehow(NSDate * d)
{
// Body
// of
// your
// function
}
Or to make a category on NSDate to do what you need:
//NSDate+AndrewsCategory.h
#import <Foundation/Foundation.h>
#interface NSDate(AndrewsCategory)
- (NSString *)Andrew_MakeAStringSomehow;
#end
//NSDate+AndrewsCategory.m
#import "NSDate+AndrewsCategory.h"
#implementation NSDate(AndrewsCategory)
- (NSString *)Andrew_MakeAStringSomehow {
// Body
// of
// your
// method
}
#end
Note the stupid prefix on the method name. That's important to keep your method names from colliding with other method names on framework classes. Usually you would use initials: your company's, yours, or the project's.
In either case, just import the relevant header where you need to use the function or method, and you should be hunky-dory.
I'd consider writing a category on NSDate. Categories let you extend the functionality of existing classes with additional methods without having to mess with the existing implementation of the class. So you can add yourMethod to NSDate, and in the future just be able to call [yourDate yourMethod].
To do this in Xcode, just hit ⌘N to create a new file, and choose Objective-C category, then give it some name and make it a category on NSDate.
Then set up your header:
#interface NSDate (YourCategory)
- (NSString *) yourMethod;
#end
And your implementation:
#implementation NSDate (YourCategory)
- (NSString *) yourMethod {
return [NSString stringWithFormat:#"yourMethod on this date: ", [self description]]; // for example
}
#end
Then just include "NSDate+YourCategory.h" in any file where you want to use yourMethod.
i'd recommend adding the method to a catagory and then adding the header to your projects pch file
#ifdef __OBJC__
#import "yourHeader.h"
#endif
if you google for NSDate+Helper that should give you an idea of the implementation.
Nik
It's probably good to put it in 1 class as a method, then have another class add this class to take advantage of it's method.
simple 1 or 2 methods NSObject subclasses won't make slightest differences in execution

how to access cache from other views

I have set up a sharedCache using ASIHttprequest and it is created from the xml I parse in my subview. I was woundering if I can then access that sharedCache from my mainview to do a few things things that will speed my tables up?
any idea, suggestions, thoughts of examples would be greatly appreciated.
There's already a sharedCache provided by ASIDownloadCache. It's visible anywhere in your application (assuming you #import "ASIDownloadCache.h"), so you should be able to call [ASIDownloadCache sharedCache] and use it.
EDIT: To use several caches is not too tricky. Create a separate class which is included by both your main view and your subview. In there, define a method to return one or more ASIDownloadCache objects, and provide an implementation, similar to this:
DownloadCaches.h
#import "ASIDownloadCache.h"
#interface DownloadCaches : NSObject
+ (ASIDownloadCache *)imageCache;
#end
DownloadCaches.m
#import "DownloadCaches.h"
#implementation DownloadCaches
static ASIDownloadCache *imageCache = nil;
+ (ASIDownloadCache *)imageCache
{
if(imageCache == nil)
{
imageCache = [[ASIDownloadCache alloc] init];
// set imageCache-specific options here
}
return imageCache;
}
#end
You only ever need to call [DownloadCaches imageCache] and it will be initialised if not already, and then returned to you.

Does calling a protocol method pass program flow control?

I know this is quite possibly a lame question, but I've pulled three consecutive all-nighters and I'm very blurry. And I'm new to Objective C and Cocoa Touch.
I've created a class that provides a delegate method. I'll use simplified example code since the specifics aren't important. The header file looks like this:
#import <Foundation/Foundation.h>
#protocol UsernameCheckerDelegate <NSObject>
#required
- (void)didTheRequestedThing:(BOOL)wasSuccessful;
#end
#interface TheDelegateClass : NSObject {
id <TheDelegateClassDelegate> tdcDelegate;
}
#property (assign) id <TheDelegateClassDelegate> tdcDelegate;
- (void)methodThatDoesSomething:(int)theValue;
#end
And the source file looks like this:
#import "TheDelegateClass.h"
#implementation TheDelegateClass
#synthesize tdcDelegate;
- (void)methodThatDoesSomething:(int)theValue {
if (theValue > 10) {
[[self tdcDelegate] didTheRequestedThing:NO];
// POINT A
}
// POINT B
int newValue = theValue * 10;
NSString *subject = [NSString stringWithFormat:#"Hey Bob, %i", newValue];
// Some more stuff here, send an email or something, whatever
[[self tdcDelegate] didTheRequestedThing:YES];
// POINT C
}
#end
Here's my question: if theValue is in fact greater than 10 and the line above POINT A runs, does program flow control pass out of this method (and back to the didTheRequestedThing delegate method in the object that called this) or does flow continue on through POINT B to POINT C?
I'm hoping for the former because I can simplify the heck out of my code, currently an unpleasant mess of deeply nested ifs and elses.
When the -didTheRequestedThing: method returns, control flow returns back to your POINT A and continues on to POINT B and POINT C. Delegate method calls are exactly like any other method call. If you want to avoid executing the rest of the method after the delegate call, just stick a call to return where your // POINT A comment is.

Set a variable in a different class

I am trying to create an application were 2 classes share a variable. Just to keep the code looking a little bit cleaner I created a 3rd class. This "third class" sole job is to house this variable.
In class 3 I put a "get" and "set" method.
SharedURL.H (Class 3)
#interface SharedURL : NSObject {
NSString *theURL;
}
-(NSString *)getTheURL;
-(void)setTheURL:(NSString *)blah;
#property (readwrite, copy) NSString *theURL;
#end
Implementation:
#import "SharedURL.h"
#implementation SharedURL
#synthesize theURL;
-(NSString *)getTheURL;
{
return theURL;
}
-(void)setTheURL:(NSString *)blah;
{
theURL=blah;
}
#end
In classes 1 and 2:
I Import the class header
I set up the instance variable like so
SharedURL *XMLURL;
I define the property like so
#property (readwrite, assign) SharedURL *XMLURL;
Then in the implementation I set the set method like this
[XMLURL setTheURL:#"http://localhost:8888/xml/MyXMLFile.xml"];
However whenever I implement the fallowing code the getter method returns nil.
NSLog(#" the url is %#", [XMLURL getTheURL]);
How can I get this to actually save the variable that I imput and then return it. I'm looking at some sample code and i cannot find my error it looks to me like I am doing it perfectly fine I think I am overlooking something stupid.
If I understand this right you are calling class 3 from either class 1 or 2 (lets say 1) and set the URL then your go to class 2 and and only ask for the URL, right?
I think your problem is that you are calling something that is independent for each object. I think you can fix this by instead of saying -(NSString *)getTheURL and -(void)setTheURL you need to change it to +(NSString *)getTheURL and +(void)setTheURL (in both the .h and .m files) making it not variable dependent.

Using selectors for callbacks?

I think i should be using selectors (or even a different paradigm), but even after R'ing TFM I can't figure out what i'm supposed to do. It's all related to callbacks from a delegate
I have my main Model object:
#implementation Model
#synthesize myConnection; // which is an NSURLConnection
...
-(void)someMethod{
MyConnectionDelegate *mcd = [[MyConnectionDelegate alloc]initWithCallingObject:self];
myConnection = [[NSURLConnection alloc] initWithRequest:requestForToken delegate:mcd];
...
}
-(void)didGetCalledBack:(NSArray *)resultArray{
NSLog(#"got the callback");
}
and then in my delegate:
#implementation MyConnectionDelegate
#synthesize callingObject; // which is of type id
#synthesize resultArray; // NSArray
-(id)initWithCallingObject:(id)caller{
...//std [self init] block
self.callingObject = caller;
return self;
...
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
...
}
//and all the other NSURLConnection delegate methods
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
...
// finish building array of results into self.resultArray
[self.callingObject didGetCalledBack:self.resultArray];
}
So...
1) I think i should be using selectors, or something else rather than hardcoding the fact that the caller (delegator?) needs to implement -didGetCalledBack:
Right? IF so, how? (and why, other than cleanliness)
2) Or is my whole implementation wrong in the way i'm attempting to use a callback from the delegate of the NSURLConnection back to the delegator wrong?
I've looked at the Apple samplecode etc but nothing i've seen ever has anything other than delegate:self. Maybe i should have delegate:self too for the NSURLConnection, but I'm making many connections and if i do delegate:self my delegate methods (like -didReceiveData:) become a big mess of if (connection ==connection1){ type code.
thanks,
richard
I think i should be using selectors, or something else rather than hardcoding the fact that the caller (delegator?) needs to implement -didGetCalledBack: Right? IF so, how? (and why, other than cleanliness)
Nothing wrong with what you are doing. You might want to consider declaring a protocol for a calling object e.g.
#protocol CallingObject <NSObject>
-(void) didGetCallBack: (NSArray*) resultArray;
#end
And then
#interface Model : NSObject <CallingObject> // ...
and
#interface MyConnectionDelegate : NSObject
{
// ...
}
-(id) initWithCallingObject: (id<CallingObject>) calller;
// ...
#end
That will give you some compile time checking that the calling object implements the required method(s).
Maybe i should have delegate:self too for the NSURLConnection, but I'm making many connections and if i do delegate:self my delegate methods (like -didReceiveData:) become a big mess of if (connection ==connection1){ type code.
Then don't use explicit comparisons - use containers or similar abstractions to react to different connections.
E.g. to use the results of connections with different controls, use a dictionary that maps from NSURLConnections to those controls so the following:
if (connection == connection1) [obj1 doStuff];
else if (connection == connection2) [obj2 doStuff];
// ...
becomes:
[[connectionClients objectForKey:connection] doStuff];