【发布时间】:2012-02-17 04:41:36
【问题描述】:
我必须说我现在感觉自己像个白痴。 :) 我一直在 Facebook、Google 和 StackOverflow 上上下下,但仍然无法得到我做错了什么的答案! :) 我查看了两个 Facebook 示例:Hackbook 和 WishList。 Wishlist 显然应该告诉我该怎么做,但是 ALL 我见过的示例将 OBJECT 部分作为 URL。我不一定希望这样,因为我只想在帖子中说(此用户)正在玩 [MyGame]。
好的,这是我的目标。我有一个 iPhone 游戏。当你听一首歌时,我想做 Spotify 所做的事情,它会发布到时间线和自动收报机上。我还想用它在用户的时间轴和股票代码上发布玩家的分数。
我使用名为 Play 的操作和名为 Game 的对象及其聚合器来设置 Open Graph。我想我还需要一个名为 Score 的操作?
无论如何,我可以使用feed 对话框成功地发布到用户的墙上,但这不是我想要的Play 操作。
这是我到目前为止所得到的简明版本,非常感谢任何帮助:
夫妻注意事项:
我有一个单身人士FacebookInfo,负责处理 Facebook 代表和其他事情。我还有一个FacebookUser 类,它保存当前会话的当前用户信息,在调用me 时填充。我还有一个 DLog 方法,它只在调试模式下执行 NSlog。
当用户在我的游戏中点击Play 按钮时,我想在下面调用我的方法[[Facebook sharedInfo] publishAction:@"play"]。我将NSString 作为操作传递,所以稍后我可以调用相同的方法并使用Score 之类的操作,然后相应地修改帖子。
@interface FacebookInfo : NSObject {
Facebook *_facebook;
FacebookUser *_facebookUser;
}
@property (nonatomic, retain) Facebook *facebook;
@property (nonatomic, retain) FacebookUser *facebookUser;
+(id)sharedInfo;
-(BOOL)isFacebookAuthenticated;
-(void)fbDidLogout;
-(void)getMe;
-(void)publishFeed;
-(void)publishWithAction:(NSString *)action;
@end
static FacebookInfo *facebookInfo = nil;
@implementation FacebookInfo
@synthesize facebook = _facebook;
@synthesize facebookUser = _facebookUser;
#pragma mark - Custom Methods
-(void)getMe {
DLog(@"**********");
/* when forcing FBConnect to show inline dialog instead of using SSO, this works.
apparently this fails when using SSO, error:
Err message: (null)
Err code: 10000
*/
[[self facebook] requestWithGraphPath:@"me" andDelegate:self];
}
-(void)publishWithAction:(NSString *)action {
DLog(@"**********");
if ([action isEqualToString:@"play"]) {
// Build the params list
NSMutableDictionary *params = [[NSMutableDictionary alloc] initWithCapacity:1];
// all sample have this pointing to a URL. Do i really need to do that?
[params setValue:kFBAppNameSpace forKey:@"game"];
// I know I may need more parameters, but which are required?
// Do I need to add the one's that Facebook Javascript examples have,
// like title, description? I think it's here where I'm mostly confused.
// Make the Graph API call to add to the wishlist
[[self facebook] requestWithGraphPath:@"me/[myappnamespace]:play"
andParams:params
andHttpMethod:@"POST"
andDelegate:self];
[params release];
}
}
-(void)publishFeed {
DLog(@"**********");
/*
This works perfectly fine
*/
SBJSON *jsonWriter = [[SBJSON new] autorelease];
NSDictionary *actionLinks = [NSArray arrayWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:
@"Get The App",@"name",
kFBAppURL,@"link",
nil],
nil];
NSString *actionLinksStr = [jsonWriter stringWithObject:actionLinks];
NSString *app_id = kFBAppID;
NSString *user_message_prompt = [NSString stringWithFormat:@"Post to Your Wall!"];
NSString *name = [NSString stringWithFormat:@"[MyGameName]"];
NSString *caption = [NSString stringWithFormat:@"%@ has gotten a score of %@!",[[self facebookUser] firstName],[[[GameInfo sharedGameInfo] scoreTotal] stringValue]];
NSString *description = [NSString stringWithFormat:@"Can you beat this score?!"];
NSString *link = kFBAppURL;
NSString *picture = kFBAppImage;
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
app_id, @"app_id",
user_message_prompt, @"user_message_prompt",
name, @"name",
caption, @"caption",
description, @"description",
link, @"link",
picture, @"picture",
actionLinksStr, @"actions",
nil];
[[self facebook] dialog:@"feed"
andParams:params
andDelegate:self];
}
-(BOOL)checkForPreviousAccessToken {
DLog(@"**********");
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:@"FBAccessTokenKey"] && [defaults objectForKey:@"FBExpirationDateKey"]) {
DLog(@"FB: Token Exists!");
[[self facebook] setAccessToken:[defaults objectForKey:@"FBAccessTokenKey"]];
[[self facebook] setExpirationDate:[defaults objectForKey:@"FBExpirationDateKey"]];
}
if (![[self facebook] isSessionValid]) {
DLog(@"FB: Authorizing...");
NSArray *permissions = [[NSArray alloc] initWithObjects:
@"publish_stream",
@"publish_actions",
@"offline_access",
nil];
[[self facebook] authorize:permissions];
[permissions release];
} else {
DLog(@"FB: Authorized!!!");
// show logged in
[self getMe];
}
return [[self facebook] isSessionValid];
}
-(BOOL)isFacebookAuthenticated {
DLog(@"**********");
return [self checkForPreviousAccessToken];
}
-(void)extendAccessTokenIfNeeded {
DLog(@"**********");
[[self facebook] extendAccessTokenIfNeeded];
[[FacebookInfo sharedInfo] getMe];
}
-(void)logout {
DLog(@"**********");
[[self facebook] logout:self];
}
#pragma mark - FBConnect Delegate Methods
-(void)fbDidLogin {
DLog(@"**********");
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[[self facebook] accessToken] forKey:@"FBAccessTokenKey"];
[defaults setObject:[[self facebook] expirationDate] forKey:@"FBExpirationDateKey"];
[defaults synchronize];
[self getMe];
}
- (void)fbDidNotLogin:(BOOL)cancelled {
DLog(@"**********");
}
- (void)fbDidExtendToken:(NSString*)accessToken expiresAt:(NSDate*)expiresAt {
DLog(@"**********");
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:accessToken forKey:@"FBAccessTokenKey"];
[defaults setObject:expiresAt forKey:@"FBExpirationDateKey"];
[defaults synchronize];
}
-(void)fbDidLogout {
DLog(@"**********");
// Remove saved authorization information if it exists
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:@"FBAccessTokenKey"]) {
[defaults removeObjectForKey:@"FBAccessTokenKey"];
[defaults removeObjectForKey:@"FBExpirationDateKey"];
[defaults synchronize];
}
}
- (void)fbSessionInvalidated {
DLog(@"**********");
}
#pragma mark - FBRequestDelegate Methods
/**
* Called when the Facebook API request has returned a response. This callback
* gives you access to the raw response. It's called before
* (void)request:(FBRequest *)request didLoad:(id)result,
* which is passed the parsed response object.
*/
- (void)request:(FBRequest *)request didReceiveResponse:(NSURLResponse *)response {
DLog(@"**********");
//DLog(@"received response");
}
/**
* Called when a request returns and its response has been parsed into
* an object. The resulting object may be a dictionary, an array, a string,
* or a number, depending on the format of the API response. If you need access
* to the raw response, use:
*
* (void)request:(FBRequest *)request
* didReceiveResponse:(NSURLResponse *)response
*/
- (void)request:(FBRequest *)request didLoad:(id)result {
DLog(@"**********");
//code removed for this example
}
/**
* Called when an error prevents the Facebook API request from completing
* successfully.
*/
- (void)request:(FBRequest *)request didFailWithError:(NSError *)error {
DLog(@"**********");
DLog(@"Err message: %@", [[error userInfo] objectForKey:@"error_msg"]);
DLog(@"Err code: %d", [error code]);
if ([error code] == 190) {
// logout
} else {
DLog(@"There was an error making your request.");
}
}
#pragma mark - Singleton Methods
+ (id)sharedInfo {
//DLog(@"**********");
@synchronized(self) {
if(facebookInfo == nil)
facebookInfo = [[super allocWithZone:NULL] init];
}
return facebookInfo;
}
+ (id)allocWithZone:(NSZone *)zone {
DLog(@"**********");
return [[self sharedInfo] retain];
}
- (id)copyWithZone:(NSZone *)zone {
DLog(@"**********");
return self;
}
- (id)retain {
DLog(@"**********");
return self;
}
- (unsigned)retainCount {
DLog(@"**********");
return UINT_MAX; //denotes an object that cannot be released
}
- (oneway void)release {
DLog(@"**********");
// never release
}
- (id)autorelease {
DLog(@"**********");
return self;
}
- (id)init {
DLog(@"**********");
if ((self = [super init]) != NULL) {
//Init
[self setFacebook:[[[Facebook alloc] initWithAppId:kFBAppID urlSchemeSuffix:kFBUrlSchemeSuffix andDelegate:self] autorelease]];
[self setFacebookUser:[[[FacebookUser alloc] init] autorelease]];
}
return self;
}
- (void)dealloc {
DLog(@"**********");
// Should never be called, but just here for clarity really.
DLog(@"Release FacebookInfo...");
[super dealloc];
}
@end
@implementation AppDelegate_iPhone
// Add for Facebook SSO support (4.2+)
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
[[[FacebookInfo sharedInfo] facebook] handleOpenURL:url];
}
// Add for Facebook SSO support (pre 4.2)
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
[[[FacebookInfo sharedInfo] facebook] handleOpenURL:url];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
DLog(@"**********");
[[FacebookInfo sharedInfo] extendAccessTokenIfNeeded];
}
哇,我知道这是一篇很长的帖子,但我希望有人能帮助我指出正确的方向。
更新 1:(2012/18/02)
好的。所以我决定制作一个包含我不想做的 og 元数据的页面,并为我的对象提供 url。根据 FB 文档,找到 here:
开放图形力学 当用户在您的应用程序中执行操作时,例如烹制 Stuffed Cookie,应用程序会调用 Graph API 来创建新的烹制操作,将用户与 Stuffed Cookie 对象联系起来。这是通过使用配方对象的 URL 向用户的 /me/myapp:cook 连接发出 HTTP POST 来完成的。然后,Facebook 将抓取对象 URL,读取元数据,并通过操作将对象连接到用户的 Graph。 下图说明了这个过程: 用户在应用程序中执行操作,例如“烹饪”“食谱” 应用调用 Graph API /me/action:object=Object_URL Facebook 将抓取对象 URL,读取其元标记并通过操作将对象连接到用户的 Graph。
如果我们可以在应用程序本身中将这些东西定义为我不需要网站的情况的参数,那就太酷了。
【问题讨论】:
-
我也想做同样的事情,比如在不创建带有元标记的关联网页的情况下发布操作。因此,本质上,它仅在创建页面之后 起作用。对吗?
-
这是正确的。截至目前,2012 年 3 月 9 日,我只能通过创建一个页面来完成此操作。
标签: objective-c ios facebook-graph-api facebook-opengraph fbconnect