#protocol on IOS parsing data 2 way? - iphone

I have login Code like this :
#protocol LoginDelegate
-(void)DUsername:(NSString *) username DPassword:(NSString *) password;
#end
#interface loginipad : UIViewController {
id<LoginDelegate> delegate;
IBOutlet UITextField *edusername;
IBOutlet UITextField *edpassword;
}
and then i use this object on mainViewController like this :
#interface mainViewController : UIViewController<LoginDelegate> {
and call this methode on mainViewController
-(void)DUsername:(NSString *) username DPassword:(NSString *) password{
userlogin=[username retain];
passlogin=[password retain];
if (!scm.isRunning) {
[scm connectToHost:#"localhost" onPort:8080];
}
}
This method is success to parsing data from login modalview to mainViewController, but i want show progress of process or any message from mainViewController to login modal view when login button is klick (i try MBPrgoressHUD but no success due i use this login on modal view).
My Question how i can parsing data from mainViewController to This login modalview ?
Thanks,
for call the method :
loginipad *plogin = [[loginipad alloc] initWithNibName:#"loginipad" bundle:nil];
plogin.delegate = self;
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:plogin];
plogin.title=#"Login";
[self presentModalViewController:nc animated:YES];
[nc release];
nc = nil;
[plogin release];
plogin = nil;

answer completely edited
Your question leads to multiple solutions and strategies.
First: general posibilities to implement bidirectional data-transfer between two classes.
via multiple protocols: loose cupling but leads to import-loops which are annoying. I know ho to solve import loops for class-definitions (#class) but I dont know how to solve this for protocols
A.h:
#import "B.h"
#protocol ADelegate
-(void) adelegate:(NSString*)data;
#end
#interface A : NSObject<BDelegate>
{
id<ADelegate> delegate;
}
#end
B.h:
#import "A.h"
#protocol BDelegate
-(void) bdelegate:(NSString*)data;
#end
#interface B : NSObject<ADelegate>
{
id<BDelegate> delegate;
}
#end
via a single protocol: dense cupling :( but no import-loop (this is a working ugly style)
A.h:
//no import here needed
#protocol ADelegate
-(void) adelegate:(NSString*)data;
#end
#interface A : NSObject<BDelegate>
{
id<ADelegate> delegate;
}
#end
B.h:
#import "A.h"
#interface B : NSObject<ADelegate>
{
A* delegate;
}
#end
via pipe/stream: bidirectional data-transfer should by done using a pipe (unbuffered) or stream (buffered)
here I show you a small and simple delegate-pipe but there also exists a NSPipe/NSStream
DelegatePipe.h
#protocol DelegatePipeDelegate
- dataArrived:(NSString*)data;
#end
#interface DelegatePipe : NSObject {
NSMutableArray *delegates;
}
-(void)open:(id<DelegatePipeDelegate>)d;
-(void)close:(id<DelegatePipeDelegate>)d;
-(void)send:(NSString*)data;
#end
DelegatePipe.m
#implementation DelegatePipe
-(id)init
{
if(self = [super init])
{
delegates = [NSMutableArray array];
}
return self;
}
-(void) dealloc
{
[delegates release];
delegates = nil;
}
-(void) open:(id <DelegatePipeDelegate>)d
{
#synchronized(self)
{
if([delegates containsObject:d])
return;
//if([delegates count]>=2) //Pipe contains originally only 2 delegates. but a broadcaster is also nice ;)
// return;
[delegates addObject:d];
}
}
-(void) close:(id <DelegatePipeDelegate>)d
{
#synchronized(self)
{
[delegates removeObject:d];
}
}
-(void) send:(NSString *)data
{
#synchronized(self)
{
for(id<DelegatePipeDelegate> d in delegates)
[d dataArrived:data];
}
}
#end
Second: KVO
KVO is often used in a ModelViewController (MVC) Pattern. eg: visualize data in a view. The network-connection-state in your case is part of data and your loginipad is a view (and a controller)
Authentificator.h
typedef enum eAuthState
{
NOT_CONNECTED = 0,
LOGIN_FAILED,
CONNECING,
CONNECTED
} AuthState;
#interface Authentificator : NSObject {
AuthState state;
}
#property (nonatomic, assign) AuthState state;
#end
Authentificator.m
...
-(void) doAuthWithUsername:(NSString*)name password:(NSString*)pw
{
self.state = CONNECING;
//do network-stuff
}
//delegate from network. here NSURLConnection
-(void) connectionDidFinishLoading:(NSURLConnection *)connection
{
//parse network-answer
BOOL success = YES;
if(success)
self.state = CONNECTED;
else
self.state = LOGIN_FAILED;
}
loginipad.h
#interface loginipad : UIViewController
{
Authentificator *auth;
}
#property (nonatomic, retain) Authentificator *auth;
#end
loginipad.m
#implementation loginipad
#synthesize auth;
//override setter for more comfortable use (add/removeObserver)
-(void) setAuth:(Authentificator *)a
{
#synchronized(auth)
{
[auth removeObserver:self forKeyPath:#"state"];
[auth release];
auth = a;
[auth retain];
[auth addObserver:self forKeyPath:#"state" options:0 context:nil];
}
}
-(IBAction) buttonClicked:(id)aSender
{
self.auth = [Authentificator sharedAuthentificator];
}
-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if(![object isKindOfClass:Authentificator.class])
return;
AuthState state = ((Authentificator*)object).state;
NSLog(#"curState: %i",state);
//do sth with state
}
- (void)dealloc {
self.auth = nil;
[super dealloc];
}

Related

Crash on Setting Delegate

I have a custom view (settingview) with nib and protocol. i want to add this view on a viewcontoller with delegate. When i set its delegate my app crashes and i don't know what i have done wrong.
i don't have NIB for ViewController.
i am attaching few images of my code and View's NIB.
.h
#protocol SettingViewDelegate
#required
-(void)CornerSlider:(id)sender;
-(void)MarginSlider:(id)sender;
-(void)BorderSlider:(id)sender;
-(void)ShadowSlider:(id)sender;
-(void)BorderColor:(id)sender;
-(void)ShadowColor:(id)sender;
-(void)remove:(id)sender;
#end
#interface SettingView : UIView
#property (nonatomic, assign) id delegate;
-(IBAction)CornerSlider1:(id)sender;
-(IBAction)MarginSlider1:(id)sender;
-(IBAction)BorderSlider1:(id)sender;
-(IBAction)ShadowSlider1:(id)sender;
-(IBAction)BorderColor1:(id)sender;
-(IBAction)ShadowColor1:(id)sender;
-(IBAction)remove1:(id)sender;
#end
.m
#implementation SettingView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self = [[[NSBundle mainBundle] loadNibNamed: #"Setting"
owner: self
options: nil] objectAtIndex:0];
}
return self;
}
-(IBAction)CornerSlider1:(id)sender
{
[self.delegate CornerSlider:sender];
}
-(IBAction)MarginSlider1:(id)sender
{
[self.delegate MarginSlider:sender];
}
-(IBAction)BorderSlider1:(id)sender
{
[self.delegate BorderSlider:sender];
}
-(IBAction)ShadowSlider1:(id)sender
{
[self.delegate ShadowSlider:sender];
}
-(IBAction)BorderColor1:(id)sender{
[self.delegate BorderColor:sender];
}
-(IBAction)ShadowColor1:(id)sender{
[self.delegate ShadowColor:sender];
}
-(IBAction)remove1:(id)sender{
[self.delegate remove:sender];
}
#end
app crashes here after setting its delegate.
SettingView *settingView=[[SettingView alloc]init];
[settingView setDelegate:self];
[self.view addSubview:settingView];
Replace #required with #optional
#protocol SettingViewDelegate
#optional
-(void)CornerSlider:(id)sender;
-(void)MarginSlider:(id)sender;
-(void)BorderSlider:(id)sender;
-(void)ShadowSlider:(id)sender;
-(void)BorderColor:(id)sender;
-(void)ShadowColor:(id)sender;
-(void)remove:(id)sender;
#end
See whether you have implemented all the methods of your delegate into your "self.view" class where you add your "Setting View". Also, see whether you had implemented "SettingsViewDelegate" into the class you add "Setting View" as subview.
For more clarification, look this https://stackoverflow.com/a/12660523/859001
Did you try
#interface BlaBlaViewController : UIViewController<SettingsViewDelegate>
I saw in your code:
-(void)setDelegate:(id)delegate
{
self.delegate = delegate;
}
This would result in an endless loop. You should use the synthesized _ivar for overloading the setter (or leave it out all together).
Mistake found. It was in IB.
I was setting Custom Class (SettingView) to File's Owner's Class. Now Its View's Custom Class and File's Owner is UIView's Class.
and now its working fine. .
Use the following setter method for delegate in the SettingsView implementation.
-(void)setDelegate:(id)adelegate
{
_delegate = adelegate;
}
Try this -
.h
#protocol SettingViewDelegate
-(void)CornerSlider:(id)sender;
-(void)MarginSlider:(id)sender;
-(void)BorderSlider:(id)sender;
-(void)ShadowSlider:(id)sender;
-(void)BorderColor:(id)sender;
-(void)ShadowColor:(id)sender;
-(void)remove:(id)sender;
#end
#interface SettingView : UIView
#property (nonatomic, assign) id delegate;
-(IBAction)CornerSlider1:(id)sender;
-(IBAction)MarginSlider1:(id)sender;
-(IBAction)BorderSlider1:(id)sender;
-(IBAction)ShadowSlider1:(id)sender;
-(IBAction)BorderColor1:(id)sender;
-(IBAction)ShadowColor1:(id)sender;
-(IBAction)remove1:(id)sender;
#end
.m
-(IBAction)CornerSlider1:(id)sender
{
if([self.delegate respondsToSelector:#(CornerSlider:)])
{
[self.delegate CornerSlider:sender];
}
}
-(IBAction)MarginSlider1:(id)sender
{
if([self.delegate respondsToSelector:#(MarginSlider:)])
{
[self.delegate MarginSlider:sender];
}
}
-(IBAction)BorderSlider1:(id)sender
{
if([self.delegate respondsToSelector:#(BorderSlider:)])
{
[self.delegate BorderSlider:sender];
}
}
-(IBAction)ShadowSlider1:(id)sender
{
if([self.delegate respondsToSelector:#(ShadowSlider:)])
{
[self.delegate ShadowSlider:sender];
}
}
-(IBAction)BorderColor1:(id)sender{
if([self.delegate respondsToSelector:#(BorderColor:)])
{
[self.delegate BorderColor:sender];
}
}
-(IBAction)ShadowColor1:(id)sender{
if([self.delegate respondsToSelector:#(ShadowColor:)])
{
[self.delegate ShadowColor:sender];
}
}
-(IBAction)remove1:(id)sender{
if([self.delegate respondsToSelector:#(remove:)])
{
[self.delegate remove:sender];
}
}

Protocol method does not get invoked, shows delegate 'nil'

I'm working on an iPad App and i'm having issue with delegate... the protocol method does not get invoked. i'm not sure what i'm missing, here is my code.
#protocol pickerLabelProtocol <NSObject>
- (void)selectedPickerData:(UILabel *)sender;
#end
#interface showPickerVC : UIViewController
#property (nonatomic, strong) id <pickerLabelProtocol> delegate;
#end
#implementation showPickerVC
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
//i used breakpoint, the 'delegate' is always nil for some reason?
[self.delegate selectedPickerData:self.mainLabel];
}
----------------------
#interface someViewController : UIViewController <pickerLabelProtocol>
#property (nonatomic, strong) showPickerVC *showPicker;
#end
#implementation someViewController
- (void)selectedPickerData:(UILabel *)sender
{
//protocol method
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.showPicker = [[showPickerVC alloc]init];
self.showPicker.delegate = self;
}
I can not got any mistake From your code but i suggest you that Be clear about when you create object of showPickerVC add it's delegate self
Such Like ,
showPickerVC *obj = [[showPickerVC alloc] init];
obj.delegate = self; /// YOur protocol delegate
.
.
[self presentModalViewController:obj animated:YES];
And Also add code as following
#implementation showPickerVC
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
if([self.delegate respondsToSelector:#selector(selectedPickerData:)])
{
[self.delegate selectedPickerData:self.mainLabel];
}
}
For More information about How to create/use of Protocol.

Why wont my singleton property autocomplete?

Anyidea why autocomplete does not work on the spaceScene property?
#import <Foundation/Foundation.h>
#import "cocos2d.h"
#class SpaceScene;
#interface SpaceSceneSingleton : NSObject
{
SpaceScene *spaceScene;
}
#property (assign) SpaceScene *spaceScene;
+(SpaceSceneSingleton*)sharedSpaceSceneSingleton;
-(void) addChildToSceneWith:(CCNode *) node andWithZindex: (int) zIndex;
-(void) runAction:(CCAction*) action;
-(void) setTouchIsEnabled:(BOOL) isEnabled;
-(void) removeChild: (CCNode *) child;
#end
#import "SpaceSceneSingleton.h"
#implementation SpaceSceneSingleton
#synthesize spaceScene;
static SpaceSceneSingleton* _sharedSpaceSceneSingleton = nil;
+(SpaceSceneSingleton*)sharedSpaceSceneSingleton;
{
#synchronized([SpaceSceneSingleton class])
{
if (!_sharedSpaceSceneSingleton)
[[self alloc] init];
return _sharedSpaceSceneSingleton;
}
return nil;
}
+(id)alloc
{
#synchronized([SpaceSceneSingleton class])
{
NSAssert(_sharedSpaceSceneSingleton == nil, #"Attempted to allocate a second instance of a singleton.");
_sharedSpaceSceneSingleton = [super alloc];
return _sharedSpaceSceneSingleton;
}
return nil;
}
-(id)init {
self = [super init];
if (self != nil) {
// initialize stuff here
}
return self;
}
-(void) addChildToSceneWith:(CCNode *) node andWithZindex: (int) zIndex
{
[self.spaceScene addChild:node z:zIndex];
}
-(void) runAction:(CCAction*) action
{
//[self.spaceScene add
}
-(void) setTouchIsEnabled:(BOOL) isEnabled
{
}
-(void) removeChild: (CCNode *) child
{
}
#end
You only declared #class SpaceScene; so within this scope nothing more is known than that a class called SpaceScene might exist. Maybe importing SpaceScene.h helps.
I would even say this should compile with warnings. Does it?

Delegate not working

I have this code in my viewController:
- (GraphModel *)graphModel
{
if (!graphModel) {
graphModel = [[GraphModel alloc] init];
NSLog(#"graphModel = %#", graphModel);
}
return graphModel;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.graphView.delegate = [self graphModel];
NSLog(#"self.graphview.delegate = %#", self.graphView.delegate);
[self updateUI];
}
but the NSLog just says (null) for self.graphview.delegate
even though the NSLog in graphModel says that I successfully created an object. How can this be?
this is the code for the graphViewDelegate
#class GraphView;
#protocol GraphViewDelegate
- (double)yValueForGraphView:(GraphView *)requestor atPosition:(int)i withPrecision:(int)precision;
- (double)scaleForGraphView:(GraphView *)requestor;
#end
#interface GraphView : UIView {
id <GraphViewDelegate> delegate;
}
#property (assign) id <GraphViewDelegate> delegate;
#end
and then I have #synthesize delegate in graphView.m
Most likely guess: graphView is nil. Calling any method on a nil object has no effect and returns nil, and the .delegate is actually a call to the getter or setter as appropriate. I recommend you add:
NSLog(#"self.graphview = %#", self.graphView);
As a quick verification.

problem with singleton and KVO

In my app , i created my custom class and i am observing one of its property using KVO ,so that if its value changed it instantly display in firstview controller object (label or .. )
sample code
myCustomClass.h
#interface myCustomClass : NSObject {
NSString * text;
}
#property (nonatomic, retain) NSString * text;
- (void)changetext;
myCustomClass.m
#implementation myCustomClass
#synthesize text;
static myCustomClass * _sharedInstance;
- (id)init
{
if ((self = [super init])) {
text = # "";
}
return self;
}
+ (myCustomClass *)sharedInstance
{
if (!_sharedInstance) {
_sharedInstance = [[myCustomClass alloc] init];
}
return _sharedInstance;
}
- (void)changetext {
text = # "changed";
}
firstViewController.h
#interface FirstViewController:UIViewController {
IBOutlet UILabel * label;
}
#property (nonatomic, retain) IBOutlet UILavel * label;
firstviewController.m
#implementation FirstViewController
#synthesize label;
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id) object change:(NSDictionary *)change context:(void *)context
{
label.text = [change valueForKey:# "new"];
}
- (void)viewDidLoad {
myCustomClass * myEngine = [myCustomClass sharedInstance];
[myEngine addObserver : self forKeyPath : # "text" options : NSKeyValueObservingOptionNew context : nil];
[myEngine changetext];
[super viewDidLoad];
}
but its not changing the data , can any one please tell me where i am wrong ?
thanks in advance
P.S : i wrote in hurry forgive me if any mistakes in writing and sorry for my bad english .
When you assign to an instance variable directly rather than going through a setter, you need to issue change notifications yourself with willChangeValueForKey: and didChangeValueForKey:. There's no magic to variable assignment.
Replace text with self.text as The observer sub-system is tied into the getter and setter methods synthesized as the property.