0

I read about Change the delegate of MGTwitterEngine and don't really get it. I hope someone can explain it again.

Based on what I know, I create a wrapper for MGTwitterEngine and setup the delegate within the wrapper. So in order to make easier, I try to have an NSArray instance for the interface which I'll pass around whenever I need it.

Here is the code for the status received:

- (void)statusesReceived:(NSArray *)statuses forRequest:(NSString *)connectionIdentifier
{
    //NSLog(@"Got statuses for %@:\r%@", connectionIdentifier, statuses);

    [statusIds setObject:statuses forKey:connectionIdentifier];
}

So I expect the sharedTwitterEngine can be accessed by any object within the project, as long I request for information first, and release the statusContainer, using the new result and pass it to my working object for later use.

I'm not sure if it is the correct way, or are there any easier ways that I missed?

Community
  • 1
  • 1
sayzlim
  • 275
  • 1
  • 2
  • 16
  • what is you don't get in the post Change the delegate of MGTwitterEngine? – sergio May 19 '11 at 07:10
  • If different view controllers handle different tasks -- like login, looking up users, querying messages, etc. then the delegate methods in your wrapper should be able to pass the responses along to the appropriate view controller. – sayzlim May 19 '11 at 07:12

1 Answers1

1

The solution proposed by the S.O. post you link could be implemented in this way:

1) create a wrapper to MGTwitterEngine; this wrapper will expose any selector you need of MGTwitterEngine and will add to each of them a parameter which identifies the view controller that is calling it;

2) your wrapper to MGTwitterEngine would act as a unique delegate to all requests sent;

3) for each request that the wrapper receives from a view controller, the wrapper will store the view controller address in a NSMutableDictionary associated to the twitter id;

4) when a response comes back, the delegate (which is the same object as the wrapper) will find out which view controller sent the request initially (by searching in the dictionary for the twitter id that came with the response), and forward the response to it.

I hope this helps....

EDIT:

this is how you could do it (I am including only 1 API call and just the relevant code):

@interface TwitterClientViewController : UIViewController <MGTwitterEngineDelegate> {
}
@end

@implementation TwitterClientViewController;

- (void)requestListOfUsers:(NSString*)username {
    [twitterEngineSingleton getListsForUser:username requestDelegate:self];
}

- (void)requestSucceeded:(NSString*)connectionIdentifier {
    NSLog(@"Hello");
}
@end

@interface AdvancedTwitterEngine : NSObject <MGTwitterEngineDelegate> {
    MGTwitterEngine* _engine;
    NSMutableDictionary* _callerIds;
}
-(NSString*)getListsForUser:(NSString*)username requestDelegate:(id<MGTwitterEngineDelegate>)delegate;
@end

@implementation AdvancedTwitterEngine;

-(void)init {
    if (self = [super init]) {
        _engine = [[MGTTwitterEngine alloc] initWithDelegate:self];
        _callerIds = <init>
    }
    return self;
}

-(NSString*)getListsForUser:(NSString*)username requestDelegate:(id<MGTwitterEngineDelegate>)delegate {
    NSString* twId = [_engine getListsForUser:username];
    [_callerIds setObject:controller forKey:twId];
    return twId;
}

//-- delegate methods

- (void)requestSucceeded:(NSString*)connectionIdentifier {
    id<MGTwitterEngineDelegate> dlg = [_callerIds objectForKey:connectionIdentifier];
    [dlg requestSucceeded:connectionIdentifier];
}

@end
sergio
  • 68,819
  • 11
  • 102
  • 123
  • 1. What do you mean by expose any selector and will add to each of them a parameter identifying viewcontroller that is calling it? – sayzlim May 19 '11 at 07:33
  • for each "required" selector in MGTwitterEngine, the wrapper will offer that same selector with an added parameter; there are many different design choice you can do here, so basically I cannot go in more detail. The idea is "extending" the MGTwitterEngine API by adding the selector that also include the "sending" view controller parameter; as to the actual request implementation, those additional selectors would simply call the base implementation found in MGTwitterEngine (after dealing with the nsdictionary stuff). – sergio May 19 '11 at 07:46
  • Sorry if I'm too slow to catch on. Basically, I should write my own method for the wrapper that use the MGTwitterEngine methods to fetch the data. If I only have one view, can you show me an example how you'll create one method within the wrapper? (Any design is fine, and if you don't mind, please stay for while... because I'm still confused) – sayzlim May 19 '11 at 08:00
  • Thanks, I can see the broad idea, except the last one. [(someSpecificController*)ctrl someSpecificMessage:connectionIdentifier]; | I'll ask again if I don't understand, can I have your IM or just ask here? – sayzlim May 19 '11 at 08:31
  • your view controller should offer a selector that you can call to notify it of the response. it is completely up to you how you define it, simply find a way to call it (from the UIViewController* pointer). in my code, I show a cast of the generic UIViewController* to your specific controller type that has the method you call. hope it is now clear. – sergio May 19 '11 at 08:35
  • Why would you want to return the twit id in your method? I've tried it, but if I want to use the information returned contained inside NSArray, how do I access it from my ViewControllers? About this: [(someSpecificController*)ctrl someSpecificMessage:connectionIdentifier]; do you have specific message you can show me? (Just the selector name). – sayzlim May 19 '11 at 09:00
  • if you want to use the info in your NSArray, you could make the NSArray an NSDictionary and associate the response to the twit id; if your view controller has the twit id (that's one reason to return it), it can access the specific response by using the twit id. the `someSpecificMessage:connectionIdentifier` could be: `responseReceivedForId:connectionID` (if you pass the id here, it is not necessary to return it from the first call, as you like). – sergio May 19 '11 at 09:15
  • It seems that I don't get the whole sender and receiver concept clearly. Can you update `responseReceivedForId:connectionID` to show me how it works in the MGTwitterEngine wrapper? – sayzlim May 19 '11 at 09:46
  • see my edited code. I changed a few things: controllers are also delegates; you register the controller/delegate with the engine with each request; the engine forward the response notification to the controller/delegate. Now, very few things are left undefined. – sergio May 19 '11 at 10:12
  • Been studying your explanation and code, but still has some questions. Why must you assign delegate in view controller header class when you already did that inside the TwitterEngine wrapper? `id`. I also don't see the reason to store connection id and "viewcontroller class address", what is the purpose? I have made a new `NSMutableDictionary *statusIds" **see updated code** where I store the statuses and connectionID. But I can't get it inside the view controller class. Can I have your IM so I can ask you directly? – sayzlim May 20 '11 at 04:39
  • The reason they you don't get to your view controller is precisely the reason why I assign the delegate when I call methods in my wrapper class, and why a keep the association between twitter id and view controllers. when `statusReceived` is called in the MGTwitterEngine, I need a way to signal the relevant view controller (otherwise it would never know), that nsdictionary provides that mechanism. (IM is not a good idea for me, sorry) – sergio May 20 '11 at 07:42