FBConnect delegate methods not called IOS - iphone

I just downloaded the facebook connect from github and none of the delegate methods are being called.
I even noticed that they did not assign the facebook.sessiondelegate = self in the viewdidload method. Therefore i assigned it but still no delegate methods called. This is really worrying because I am trying to get some user data and none of the call back methods are called.
Anyone knows why ?

Ok basically if it does the authentication via Safari, there is no way to get call backs. One way to solve this is force the in app login by forcing the trysafariauth = no .

Related

Cocoa Design Patterns for Authentication

After developing for iOS for some time now, I have gotten comfortable with the language and am trying to get better at designing well-structured applications. Initially my focus was on seeing something functional, so I ended up with gigantic view controllers which were horribly architected. Now, I'm learning to separate my model classes and trying to keep my architecture more modular. I would greatly appreciate any advice on the following sample situation:
I am developing an app which (among other things) pulls a list of articles from a server and displays them. However, the user has to be authenticated to be able to retrieve this list. Because other aspects of the application utilize the same authentication, I want a single class to manage the authentication. The goal is that when any controller requests data from the model which requires authentication, if the user is not authenticated, the authentication prompt will automatically be presented.
I expect to create the following:
VIEW
- ArticlesView
- AuthenticationView
CONTROLLER
- ArticlesViewController
- AuthenticationViewController
- ArticleManager (singleton)
- AuthenticationProvider (singleton)
MODEL
- Article
When the application first loads, execution will reach the ArticlesViewController's viewDidLoad method. In this method, I get a shared instance of the ArticleManager, specify the authentication class to be the authentication provider, and ask it for a list of recent articles.
// ArticlesViewController.m
-(void) viewDidLoad {
...
AuthenticationProvider *authProvider = [AuthenticationProvider sharedInstance];
[[ArticleManager sharedInstance] setAuthenticationProvider:authProvider];
[[ArticleManager sharedInstance] fetchNewArticles];
}
If no authentication was necessary, the ArticleManager would successfully retrieve the list from the server and post a notification letting anyone interested know that the articles have been retrieved. The ArticlesViewController would handle this notification:
// ArticlesViewController.m
- (void) handleNewArticlesNotification:(NSNotification *)note {
[self updateUI];
}
However, if authentication is required, the user needs to be presented with a login screen before the articles can be fetched and displayed. So I imagine the ArticleManager doing something like this:
// ArticleManager.m
- (void) fetchNewArticles {
if( [self.authenticationProvider isAuthenticated] ){
// go fetch list from the web
}
else {
[self.authenticationProvider presentAuthenticationRequest];
}
}
Now, at this point I run into some difficulty fleshing out the remainder of the details. The AuthenticationProvider could present the AuthenticationViewController as a modal view controller from the AppDelegate's window's rootViewController and AuthenticationProvider would be the delegate of AuthenticationViewController. The AuthenticationViewController would probably be dumb to the actual actions that it is taking, and would have it's delegate (AuthenticationProvider) do the work to authenticate the user. Once the user is authenticated, AuthenticationProvider would dismiss the modal view controller (AuthenticationViewController).
But how does ArticleManager get notified that the authentication that it requested has completed? It would need to be able to handle both successful and failed authentication attempts separately. A successful authentication would eventually result in fetchNewArticles being called again.
One thought is for ArticleManager to be a delegate of AuthenticationProvider. This seems to work in this case, but there are other Model Managers which could also rely on AuthenticationProvider. Presumably this would be resolved if AuthenticationProvider is not a singleton. Would that be a decent design approach?
Thanks for taking the time to help me understand a good design approach. I have coded this a couple of times, but always get stuck/confused toward the end. Also, if the entire approach needs to be re-architected, please feel free to point me in another direction.
Many thanks!
I have always used Global NSNotifications to post when a user has logged in or logged out. Every view controller that presents data differently can subscribe to those notifications and update themselves accordingly when an event happens.
This is nice, because you may already have other views (perhaps in other tabs) that have already loaded and will need to refresh when a user has logged in or out.
One thought is for ArticleManager to be a delegate of
AuthenticationProvider. This seems to work in this case, but there are
other Model Managers which could also rely on AuthenticationProvider.
Presumably this would be resolved if AuthenticationProvider is not a
singleton. Would that be a decent design approach?
Perhaps instead you could have the AuthenticationProvider singleton provide AuthenticationSession objects, set the caller as the delegate of the AuthenticationSession, and ask the AuthenticationSession to perform the authentication.

ShareKit for iphone - SHKShareTypeText

I am using ShareKit for iphone to share some text in facebook. Can any one tell me which delegate is called after publishing the text successfully. I need this to inform the user that his action was successful.
The shareDelegate property in SHKSharer isn't the easiest to get to and change, but there are notifications sent from the delegate methods of SHKSharer, one for each of the methods: SHKSendDidStartNotification, SHKSendDidFinish, SHKSendDidCancel, SHKSendDidFailWithError. Observing these notifications turns out to be a simple way of listening for the outcome of sharing.
See shareDelegate property of SHKSharer . All the concrete sharers (e.g. SHKFacebook) extend this base class.
Having said that, I'm not sure where you set a class to be the delegate using ShareKit's public API (so I'm not claiming this to be a complete answer).

Zend Controller Plugins vs Subclassing Action Controller

I've got a pretty standard ACL system in my application. There's a Login controller and a bunch of other controllers redirecting back to Login if user is not authorized. I use a Controller Plugin for checking the ID and redirecting and I obviously don't want Login controller and Error controller to perform such a redirect.
Now I've read several times that using Controller Plugins is a better practice than subclassing the Action Controller. Yet what I see is it's much easier to extend all my controllers from this abstract base controller class which performs the necessary checking in its init method, except for the Login controller which extends Zend_Controller_Action directly.
So the question is, is there a way to attach the plugin to the controllers selectively? Of course I can always make an array out of certain controllers, send it to a plugin through a setter method and do something like:
$controller = $request->getParam('controller');
if (count($this->exceptions))
if (in_array($controller, $this->exceptions)) return;
//...check ID, perform redirect, etc...
Yet something tells me it's not the best way doing it.
And advices?
EDIT 1: #Billy ONeal
Thank you for your reply, but I don't quite catch. I can do
public function init()
{
$this->getRequest()->setParam('dropProtection', true);
}
(or run some method that sets some private variable of the plugin) in my login controller, and then say if 'dropProtection' is not true then check the user ID. But the actual dispatch process looks like this:
Plugin::dispatchLoopStartup
Plugin::preDispatch
Controller::init
Plugin::postDispatch
Plugin::preDispatch
Plugin::postDispatch
Plugin::dispatchLoopShutdown
So I cannot check this 'dropProtection' param earlier than in Plugin::postDispatch and that's a bit late. (by the way, why the preDispatch and postDispatch are being called twice?)
If you want to do it earlier, I think you can use the first method (passing an array of exceptions to the plugin) and test the module name or the controller name in routeShutdown.
Personnaly I use an action helper to check the auth in all my actions. It's more flexible and give me more control. It's only one line for each private action.
And DON'T SUBCLASS your action controller. I did it on one of my project and now my base class is a piece of shit. Use action helper instead.
is there a way to attach the plugin to the controllers selectively?
Of course. Just don't register the plugin if the request doesn't contain the parameters you're looking for. Alternately, assume all pages are protected, and have those pages which should not be protected call some method on your plugin during the init stage.
If you want to protect just a single controller, you could reverse that -- have the plugin only take action if there's some method called during the init stage.
Finally, you could make the entire logged-in section of the page it's own module, which would allow you to have the plugin check for that module before checking credentials and redirecting.

canOpenUrl and tel://

I'm having trouble understanding how this method works.
From the documentation, it specifies:
canOpenURL: Returns whether an
application can open a given URL
resource.
- (BOOL)canOpenURL:(NSURL *)url
Parameters url A URL object that
identifies a given resource. The URL’s
scheme—possibly a custom
scheme—identifies which application
can handle the URL.
Return Value NO if no application is
available that will accept the URL;
otherwise, returns YES.
Discussion This method guarantees that
that if openURL: is called, another
application will be launched to handle
it. It does not guarantee that the
full URL is valid.
Availability Available in iPhone OS
3.0 and later. Declared In UIApplication.h
Specifically, if it:
guarantees that that if openURL: is called, another application will be launched to handle it.
Then for example, if I pass in tel://HELLOWORLD, it returns YES, and when I'm attempting to openUrl, the phone application is not calling it. Nothing happens, so I'm assuming the full url is not valid when attempting to dial the number.
I understand that it does not validate the full URL, but by design, why is it not showing me an error or something if I am unable to dial the number?
Basically what I'm wondering is: what is it exactly validating?
I'm not convinced that it just checks for the handler type and the apps that support that specific handler (tel:// in this case will not work for iPod Touch for example.).
Validation is not the purpose of this function. It is only checking whether there is an application registered for this url scheme.
E.g. on the iPod touch or iPad, there is no phone app, and thus canOpenURL will return NO for tel: urls.
Or if you ask it for an url with the foo: scheme, it will return true if the user device has any App installed that claims to handle this scheme.
It can't possible validate the url, because it doesn't know anything about the foo scheme or whatever scheme the next app developer comes up with. And you won't want to load the App to validate the url at this point, either.
From the docs:
Discussion
This method guarantees that
that if openURL: is called, another
application will be launched to handle
it. It does not guarantee that the
full URL is valid.

How to receive UIAccessibilityNotifications in iPhone App

I'm interested in capturing UI changes in my application programmatically and thought that the UIAccessibility protocol may help. I've found how to post UIAccessibilityLayoutChangedNotification and UIAccessibilityScreenChangedNotification but I'm not sure how to register to receive these notifications.
I've tried using NSNotificationCenter, but the name param expects a string, while the two notifications above are of the type UIAccesibilityNotifications which is an int.
Any idea how to register for these notifications?
Thanks!
That's a great question! Unfortunately you cannot receive these "notifications" without affecting normal behavior. (i.e. "no you can't")
If you disassemble UIKit, you'll find UIAccessibilityPostNotification is implemented like this:
static void (*__UIAccessibilityBroadcastCallback)(UIAccessibilityNotifications notification, id argument);
void UIAccessibilityPostNotification(UIAccessibilityNotifications notification, id argument) {
__UIAccessibilityBroadcastCallback (notification, argument);
}
That means these accessibility "notifications" aren't any normal notifications. Rather, they are just parameters to an internal callback function. How the callback function is implemented depends on the accessibility bundle you're using.
You can replace the callback function with your own using the undocumented API _UIAccessibilitySetBroadcastCallback:
void _UIAccessibilitySetBroadcastCallback(void (*replacement)(UIAccessibilityNotifications notification, id argument)) {
__UIAccessibilityBroadcastCallback = replacement;
}
However, there isn't a corresponding "get" function (not even private), so once you set it, the original listeners cannot be notified again.