Mac Cocoa |
Author |
Message |
Ike Kapetan
Joined: 17 Jun 2006 Posts: 3136 Location: Europe
|
Posted: Fri Aug 12, 2011 6:26 pm Post subject: Facebook, Twitter & Other Social APIs |
|
|
techcrunch.com - Facebook Wins “Worst API” in Developer Survey
"A survey of over 100 developers, previously posted here on Hacker News,
aimed to determine which external APIs were the most difficult to integrate
into developers’ projects. The winner…or rather, the loser? Facebook." |
|
Back to top |
|
|
delovski
Joined: 14 Jun 2006 Posts: 3524 Location: Zagreb
|
|
Back to top |
|
|
delovski
Joined: 14 Jun 2006 Posts: 3524 Location: Zagreb
|
Posted: Sun Aug 14, 2011 4:29 pm Post subject: |
|
|
Most of other iOS books published by Apress can be fully consumed with
only the listings in the book. The download was somewhat optional. And
that was the case at least for the books without the word 'Projects' in the
title.
As I started with the iOS/Facebook/Twitter book it became obvious that the
code is somewhat different from what was described in the book. Other
Appress titles I have are very consistent in that regard. Maybe that's why
those books were postponed several times. For better or worse, this book
was finished rather quick and material was very complex and now I have
to take everything from it using things I learned elsewhere.
The project I combined from instructions in the book with some additional
lines from the download wouldn't even compile so I had to go on making
changes on my own and now I seem to understand what are the main dif-
ferences between the book and the sample code.
Interface Builder files are not used in the project even though the book does
not say we should uncheck XIB when we're creating UIViewController class.
Worse, they even remove MainWindow.xib from the project (and plist) but
fail to tell us about it.
Facebook object ends up as a global variable in the code. The book tells us
to add it as a property to the application delegate. As for the FBSession-
Delegate, the UIView subclass takes that responsibility, and that is maybe
the most unusual thing in the whole example.
In other words, I just had to change few things. This goes equally to the
projects from chapter 4 and 5, but I'll concentrate here on chapter 5 as
it is a more complete project that will be used for the rest of the book.
Ah, yes. The book doesn't say where the Facebook button graphics comes
from. The sample code reveals it is from the FBConnect.bundle found in
the /sample folder in the Facebook SDK. Not too far is the definition of the
FBLoginButton class.
Last edited by delovski on Sun Aug 14, 2011 10:38 pm; edited 4 times in total |
|
Back to top |
|
|
delovski
Joined: 14 Jun 2006 Posts: 3524 Location: Zagreb
|
Posted: Sun Aug 14, 2011 10:07 pm Post subject: AppDelegate.h |
|
|
Code: | #import <UIKit/UIKit.h>
#import "Facebook.h"
#define kFacebookAppID @"1xxxxxxxxxxxxxxx"
@class MainViewController;
@interface AppDelegate: NSObject <UIApplicationDelegate> {
UIWindow *window;
MainViewController *mainViewController;
Facebook *facebook;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) MainViewController *mainViewController;
@property (nonatomic, retain) Facebook *facebook;
@end |
Last edited by delovski on Sun Aug 14, 2011 10:19 pm; edited 1 time in total |
|
Back to top |
|
|
delovski
Joined: 14 Jun 2006 Posts: 3524 Location: Zagreb
|
Posted: Sun Aug 14, 2011 10:09 pm Post subject: AppDelegate.m |
|
|
Only the interesting parts:
Code: | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
facebook = [[Facebook alloc] initWithAppId:kFacebookAppID];
mainViewController = [[MainViewController alloc] initWithFacebook:facebook];
// Override point for customization after application launch.
[self.window addSubview:mainViewController.view];
[self.window makeKeyAndVisible];
return (YES);
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
return ([facebook handleOpenURL:url]);
} |
|
|
Back to top |
|
|
delovski
Joined: 14 Jun 2006 Posts: 3524 Location: Zagreb
|
Posted: Sun Aug 14, 2011 10:10 pm Post subject: MainViewController.h |
|
|
Code: | #import <UIKit/UIKit.h>
#import "Facebook.h"
@class FBLoginButton;
@interface MainViewController : UIViewController <FBSessionDelegate> {
Facebook *facebook;
FBLoginButton *fbLoginButton;
}
@property (nonatomic, retain) Facebook *facebook;
@property (nonatomic, retain) FBLoginButton *fbLoginButton;
- (id)initWithFacebook:(Facebook *)fb;
@end |
|
|
Back to top |
|
|
delovski
Joined: 14 Jun 2006 Posts: 3524 Location: Zagreb
|
Posted: Sun Aug 14, 2011 10:12 pm Post subject: MainViewController.m |
|
|
Here I moved evrything from the MainView class. The Facebook button is
created here. Unlike in the original code, the release message is sent in
-dealloc, not at the creation. Plus, this class serves as FBSessionDelegate.
Code: | - (id)initWithFacebook:(Facebook *)fb
{
if (self = [super initWithNibName:nil bundle:nil]) {
// Custom initialization.
self.facebook = fb;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
fbLoginButton = [[FBLoginButton alloc] initWithFrame:CGRectMake(127.0f, 68.0f, 72.0f, 37.0f)];
fbLoginButton.backgroundColor = [UIColor clearColor];
[fbLoginButton addTarget:self action:@selector(fbButtonClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:fbLoginButton];
fbLoginButton.isLoggedIn = NO;
[fbLoginButton updateImage];
// [fbLoginButton release];
}
...
- (void)dealloc
{
[facebook release];
[fbLoginButton release];
[super dealloc];
}
#pragma mark -
/**
* Show the authorization dialog.
*/
- (void)login
{
[facebook authorize:[NSArray arrayWithObjects:@"read_stream", @"offline_access",nil]
delegate:self];
}
/**
* Invalidate the access token and clear the cookie.
*/
- (void)logout
{
[facebook logout:self];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// IBAction
/**
* Called on a login/logout button click.
*/
- (void)fbButtonClick:(UIButton *)sender
{
if (fbLoginButton.isLoggedIn) {
[self logout];
}
else {
[self login];
}
}
#pragma mark -
#pragma mark FBSessionDelegate
//Called when the user successfully logged in.
- (void)fbDidLogin
{
NSLog (@"did login");
fbLoginButton.isLoggedIn = YES;
[fbLoginButton updateImage];
}
//Called when the user dismissed the dialog without logging in.
- (void)fbDidNotLogin:(BOOL)cancelled
{
NSLog(@"did not login");
}
//Called when the user logged out.
- (void)fbDidLogout
{
NSLog(@"did logout");
fbLoginButton.isLoggedIn = NO;
[fbLoginButton updateImage];
} |
Last edited by delovski on Mon Aug 15, 2011 4:13 pm; edited 1 time in total |
|
Back to top |
|
|
delovski
Joined: 14 Jun 2006 Posts: 3524 Location: Zagreb
|
Posted: Sun Aug 14, 2011 10:17 pm Post subject: |
|
|
MainView is not used for anything now, so there's nothing there, just one
empty UIView subclass. |
|
Back to top |
|
|
delovski
Joined: 14 Jun 2006 Posts: 3524 Location: Zagreb
|
Posted: Mon Aug 15, 2011 4:21 pm Post subject: |
|
|
Twitter example is more complex, it has more external code, needs three
delegates to work, but is better structured so I made only few changes. I did
follow the text in the book to some degree, so InterfaceBuilder files are still
in my project.
The project is created with the WindowBased template. Then I added a new
group with the name Twitter. In it I dragged three framework folders from
the "Twitter+OAuth" folder, namely: Libraries & Headers, MGTwitterEngine
and SAOAuthTwitterEngine. On top of that, I added the TwitterLoginButton. |
|
Back to top |
|
|
delovski
Joined: 14 Jun 2006 Posts: 3524 Location: Zagreb
|
Posted: Mon Aug 15, 2011 4:24 pm Post subject: MainViewController.h |
|
|
Code: | #import <UIKit/UIKit.h>
#import "SA_OAuthTwitterController.h"
@class TwitterLoginButton;
@interface MainViewController : UIViewController <SA_OAuthTwitterControllerDelegate> {
TwitterLoginButton *twitterLoginButton;
SA_OAuthTwitterEngine *sa_OAuthTwitterEngine;
}
@property (nonatomic, retain) TwitterLoginButton *twitterLoginButton;
@property (nonatomic, retain) SA_OAuthTwitterEngine *sa_OAuthTwitterEngine;
- (id)initWithOAuthTwitterEngine:(SA_OAuthTwitterEngine *)oaTwitterEngine;
@end |
|
|
Back to top |
|
|
delovski
Joined: 14 Jun 2006 Posts: 3524 Location: Zagreb
|
Posted: Mon Aug 15, 2011 4:24 pm Post subject: MainViewController.m |
|
|
Code: | - (id)initWithOAuthTwitterEngine:(SA_OAuthTwitterEngine *)oaTwitterEngine
{
if (self = [super initWithNibName:nil bundle:nil]) {
// Custom initialization.
self.sa_OAuthTwitterEngine = oaTwitterEngine;
}
return (self);
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
twitterLoginButton = [[TwitterLoginButton alloc] initWithFrame:CGRectMake(127.0f, 168.0f, 72.0f, 37.0f)];
twitterLoginButton.backgroundColor = [UIColor clearColor];
[twitterLoginButton addTarget:self action:@selector(twitterButtonClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:twitterLoginButton];
if ([sa_OAuthTwitterEngine isAuthorized])
twitterLoginButton.isLoggedIn = YES;
else
twitterLoginButton.isLoggedIn = NO;
[twitterLoginButton updateImage];
}
...
- (void)dealloc
{
[twitterLoginButton release];
[sa_OAuthTwitterEngine release];
[super dealloc];
} |
Last edited by delovski on Mon Aug 15, 2011 4:26 pm; edited 1 time in total |
|
Back to top |
|
|
delovski
Joined: 14 Jun 2006 Posts: 3524 Location: Zagreb
|
Posted: Mon Aug 15, 2011 4:25 pm Post subject: |
|
|
Code: | #pragma mark -
/**
* Show the authorization dialog.
*/
- (void)login
{
UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine:sa_OAuthTwitterEngine
delegate:self];
if (controller)
[self presentModalViewController: controller animated: YES];
else
[sa_OAuthTwitterEngine sendUpdate: [NSString stringWithFormat: @"Already Updated. %@", [NSDate date]]];
}
/**
* Invalidate the access token and clear the cookie.
*/
- (void)logout
{
[sa_OAuthTwitterEngine clearAccessToken];
twitterLoginButton.isLoggedIn = NO;
[twitterLoginButton updateImage];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// IBAction
/**
* Called on a login/logout button click.
*/
- (void)twitterButtonClick:(UIButton*)sender
{
if (twitterLoginButton.isLoggedIn)
[self logout];
else
[self login];
}
#pragma mark
#pragma mark SA_OAuthTwitterControllerDelegate
- (void)OAuthTwitterController:(SA_OAuthTwitterController *) controller authenticatedWithUsername: (NSString *) username {
NSLog(@"Authenicated for %@", username);
twitterLoginButton.isLoggedIn = YES;
[twitterLoginButton updateImage];
}
- (void)OAuthTwitterControllerFailed: (SA_OAuthTwitterController *) controller {
NSLog(@"Authentication Failed!");
}
- (void)OAuthTwitterControllerCanceled: (SA_OAuthTwitterController *) controller {
NSLog(@"Authentication Canceled.");
}
|
|
|
Back to top |
|
|
delovski
Joined: 14 Jun 2006 Posts: 3524 Location: Zagreb
|
Posted: Wed Aug 17, 2011 8:58 pm Post subject: |
|
|
Strange method I found in FBRequest.m in Facebook SDK.
Code: | + (NSString*)serializeURL:(NSString *)baseUrl
params:(NSDictionary *)params
httpMethod:(NSString *)httpMethod {
NSURL* parsedURL = [NSURL URLWithString:baseUrl];
NSString* queryPrefix = parsedURL.query ? @"&" : @"?";
NSMutableArray* pairs = [NSMutableArray array];
for (NSString* key in [params keyEnumerator]) {
if (([[params valueForKey:key] isKindOfClass:[UIImage class]])
||([[params valueForKey:key] isKindOfClass:[NSData class]])) {
if ([httpMethod isEqualToString:@"GET"]) {
NSLog(@"can not use GET to upload a file");
}
continue;
}
NSString *escaped_value = (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL, /* allocator */
(CFStringRef)[params objectForKey:key],
NULL, /* charactersToLeaveUnescaped */
(CFStringRef)@"!*'();:@&=+$,/?%#[]",
kCFStringEncodingUTF8);
[pairs addObject:[NSString stringWithFormat:@"%@=%@", key, escaped_value]];
[escaped_value release];
}
NSString* query = [pairs componentsJoinedByString:@"&"];
return [NSString stringWithFormat:@"%@%@%@", baseUrl, queryPrefix, query];
} |
How on earth does this work if [params objectForKey:key] indeed is an
instance of UIImage or NSData? |
|
Back to top |
|
|
delovski
Joined: 14 Jun 2006 Posts: 3524 Location: Zagreb
|
Posted: Fri Aug 19, 2011 11:11 pm Post subject: |
|
|
Crazy, started playing with the api and nothing seem to work as expected.
I have added permissions and everything, but I can't get the photos. And,
it seems as if I am not the only one!
fbDev - Get User Photos Using Graph API returns empty array
"I have found the solution to display picture. In fact after getting access
token with the specific permissions of user_photos and user_photo_video_tags
you need to first fetch the albums
$albums = $facebook->api('/me/albums?access_token='.$session['access_token']);
Now you can iterate $albums and for each specific album you can use the
following call to fetch the photos in that particular album
$photos=$facebook->api('/'.$album['id'].'photos?access_token='.$session['access_token']);
Perhaps this might help you." |
|
Back to top |
|
|
Ike Kapetan
Joined: 17 Jun 2006 Posts: 3136 Location: Europe
|
|
Back to top |
|
|
Ike Kapetan
Joined: 17 Jun 2006 Posts: 3136 Location: Europe
|
Posted: Tue May 15, 2012 2:21 pm Post subject: |
|
|
blog.mobtest.com - Here’s why the Facebook iOS app is so bad
(UIWebViews and no Nitro)
"I did some network sniffing (I like sniffing ) and found out that the data
that the iOS app downloads from facebook.com is a mixture of REST (XML
format, no JSON) and HTML. The HTML is used for your personal timeline,
and profile and groups timelines." |
|
Back to top |
|
|
delovski
Joined: 14 Jun 2006 Posts: 3524 Location: Zagreb
|
Posted: Sun Jul 22, 2012 2:56 am Post subject: |
|
|
so - facebook ios sdk - trouble posting photo using UIImage
"I see in the Facebook documentation that the "picture" key is supposed to
use the URL to an image. But I've seen some examples online that indicate
that folks are using an UIImage instead of just an URL." |
|
Back to top |
|
|
delovski
Joined: 14 Jun 2006 Posts: 3524 Location: Zagreb
|
Posted: Sun Aug 19, 2012 2:48 pm Post subject: |
|
|
so - iOS application integration with pinterest
"I made a pinterest integration in my iPad app. But, because Pinterest
doesn't have an API for posting yet, I used the following method. I just
create programmatically an HTML Web Page and add a Pin it button to
that page programmatically. Then I show a Web View and allow user to
click Pin it once more. These are more explained steps.
1) Create a WebViewController, that has a UIWebView..." |
|
Back to top |
|
|
Ike Kapetan
Joined: 17 Jun 2006 Posts: 3136 Location: Europe
|
Posted: Wed Aug 29, 2012 2:45 am Post subject: |
|
|
reddit - reddit api documentation
"This is automatically-generated documentation for the reddit API.
The reddit API and code are open source. Found a mistake or interested in
helping us improve? Have a gander at api.py and send us a pull request."
Related: We just added JSONP to reddit's JSON API. |
|
Back to top |
|
|
delovski
Joined: 14 Jun 2006 Posts: 3524 Location: Zagreb
|
Posted: Thu Jun 20, 2013 10:36 pm Post subject: |
|
|
Nijiko Yonskai - the oauth bible
"I tried to make this as understandable as possible for any party reading
it which means that the wording, references, and terminology used may
not reflect that of a technical paper or resource. Excuse me if you may for
I wish all to understand this, and not just those with a degree in understan-
ding technical jargon." |
|
Back to top |
|
|
delovski
Joined: 14 Jun 2006 Posts: 3524 Location: Zagreb
|
Posted: Mon Sep 02, 2013 10:41 pm Post subject: |
|
|
so - Change “shared via iOS” to "shared via <AppName>
"You do have to contact Facebook to change the default "shared via iOS".
I'm not sure what the best way to contact facebook but luckily the docu-
mentation describes some alternatives to change the post attribution." |
|
Back to top |
|
|
delovski
Joined: 14 Jun 2006 Posts: 3524 Location: Zagreb
|
|
Back to top |
|
|
delovski
Joined: 14 Jun 2006 Posts: 3524 Location: Zagreb
|
Posted: Wed Oct 16, 2013 11:00 pm Post subject: |
|
|
so - FBWebDialog disappears when presented in iOS 7
"FBWebDialog disappears with a flash when it is presented in iOS 7. It shows
up if I relaunch the application. It appears properly in iOS 5 and iOS 6. " |
|
Back to top |
|
|
delovski
Joined: 14 Jun 2006 Posts: 3524 Location: Zagreb
|
Posted: Tue Jan 07, 2014 9:49 pm Post subject: |
|
|
reddit - OAuth: Mobile authorization flow now enabled
"We have added a mobile friendly version of the authorization page for
developers using OAuth for mobile applications." |
|
Back to top |
|
|
Ike Kapetan
Joined: 17 Jun 2006 Posts: 3136 Location: Europe
|
|
Back to top |
|
|
|