Skip to content
This repository has been archived by the owner on Mar 9, 2021. It is now read-only.

Login without Safari for iOS #10

Closed
wants to merge 3 commits into from
Closed

Conversation

shuitic
Copy link

@shuitic shuitic commented Feb 6, 2014

I rejected my iPhone app using Pocket API by Apple, because of following reason today.
**
We found the following issues with the user interface of your app: The app opens a web page in mobile Safari for logging in, then returns the user to the app. The user should be able log in without opening Safari first.
**
So I had made login api not to use safari. I hope you like this.

@maicki
Copy link
Contributor

maicki commented Mar 18, 2015

For security reasons, Pocket's Developer TOS states: "Please send the user to the URL via their default browser in a new tab; do not present this page in a webview or screen within your application."

Therefore, we are closing this pull request and are not merging it into our SDK.

@maicki maicki closed this Mar 18, 2015
@Dids
Copy link

Dids commented Mar 31, 2015

Apps/updates using Pocket are now being rejected due to Pocket opening Safari when the app is not installed.

@mohamed-aleem
Copy link

same problem here, apple rejected the app due to signing in outside the app from safari. how will pocket handle this problem ???

@Dids
Copy link

Dids commented Apr 3, 2015

I'll post my "emergency solution" tomorrow. Essentially, I had to hijack the openURL method for the Pocket login, then show the login in an in-app browser, and parse the response in the app.
This way, Apple is okay with it, even though Pocket doesn't like the approach.

@Dids
Copy link

Dids commented Apr 4, 2015

First, you need to subclass UIApplication, then override the openURL method, like so:

- (BOOL)openURL:(NSURL*)url
{
    NSLog(@"Open url: %@", url);

    if ([[url host] isEqualToString:@"getpocket.com"])
    {
        [[NSNotificationCenter defaultCenter] postNotificationName:ApplicationOpenPocketAuthNotification object:url];
        return NO;
    }

    return [super openURL:url];
}

Next, you need to add the NSPrincipalClass key to your Info.plist, with the value being the name of your custom UIApplication subclass:

<key>NSPrincipalClass</key>
<string>CustomApplication</string>

Now, in my case I'm using SVWebViewController, but you might as well be using your custom browser. In any case, you can fins SVWebViewController here, if you want to do this the quickest way: https://github.com/TransitApp/SVWebViewController

The basic idea is that the subclassed UIApplication will send an NSNotification when the openURL method is triggered, with the notification containing the original URL.

Somewhere in your app, you need to add an observer for this notification, then open a custom web view using the URL passed from the notification.

In my case I had to handle the presentation/dismissal of the web view in a couple of places, but that's generally all that you'll need to do to get it to work.

I hope this helps, even though I had to write this in a hurry. :)

@mohamed-aleem
Copy link

Thanks Dids, well done. but it would be great if you can share with us how you handle the webview response and where to indicate in the pocketapi that you are "logged in".

@Dids
Copy link

Dids commented Apr 4, 2015

Before this whole issue, I was using the following observers for keeping track of the login state:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pocketLoginStarted:) name:PocketAPILoginStartedNotification.copy object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pocketLoginFinished:) name:PocketAPILoginFinishedNotification.copy object:nil];

These work well with the in-app web view, and I'm currently not doing anything in pocketLoginStarted.
In pocketLoginFinished, however, I'm just sending a notification to dismiss the web view:

[[NSNotificationCenter defaultCenter] postNotificationName:@"DISMISS_POCKET_LOGIN_BROWSER" object:nil];

@Dids
Copy link

Dids commented Apr 4, 2015

That should really be all, as long as you've previously implemented the Pocket SDK. Pocket SDK will handle the login request (or cancellation) from the web view, without any extra work.

@mohamed-aleem
Copy link

are you able to make requests then with the pocket sdk ?, i tried this before, but pocket won't logged in until you give it accesstoken or whatever returned after a successful login request.

@Dids
Copy link

Dids commented Apr 4, 2015

With the above implementation, there's no need to handle the tokens or the login process by yourself, as all you're really doing is hacking UIApplication to intercept the initial login request that's initiated by Pocket.
Next, you store that login request URL, send it to your own web view (as opposed to Safari), then when the web view completes, it sends the callback/finish request back to your app, just like how it did with Safari.

@mohamed-aleem
Copy link

ohh, i got it. Thanks Dids and good luck for your app

@Dids
Copy link

Dids commented Apr 4, 2015

Glad to hear it makes sense now. ;)

Oh and I can confirm that I just had two app updates go through review just fine after the change.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants