简体   繁体   English

FBConnect iOS SDK publish_action问题

[英]FBConnect iOS SDK publish_action Issue

I must say I feel like an idiot right now. 我必须说我现在感觉像个白痴。 :) I've been up and down Facebook, Google and StackOverflow and still cannot get the answer to what I am doing wrong! :)我在Facebook,Google和StackOverflow上走来走去,仍然找不到我做错了什么的答案! :) I've looked at both Facebook examples: Hackbook and WishList . :)我已经看了两Facebook的例子: HackbookWishList Wishlist is obviously the one that should tell me what to do, but ALL the examples I've seen have the OBJECT part as a URL. Wishlist显然是应该告诉我怎么做的人,但是我所看到的所有示例都将对象部分作为URL。 I do not necessarily desire this, as I just want the post to say (this user) is playing [MyGame] . 我不一定希望这样做,因为我只想发帖说(此用户)正在玩[MyGame]

Ok here's my goal. 好的,这是我的目标。 I have an iPhone game. 我有一个iPhone游戏。 I want to do what Spotify does when you listen to a song, which posts to timeline and ticker. 我想做Spotify在听一首歌曲时做的事情,这首歌会发布到时间轴和股票行情指示器上。 I'd also like to use this to post the player's score on the user's timeline and ticker. 我还想用它在用户的时间轴和股票报价中发布玩家的分数。

I setup Open Graph with an action called Play and an object called Game along with it's aggregator. 我用一个名为Play的动作和一个名为Game的对象及其聚合器来设置Open Graph。 I think I also will need an action called Score ? 我想我还需要一个名为Score的动作?

Anyways, I can successfully post to a user's wall using feed dialog, but that's not what I want for the Play action. 无论如何,我可以使用feed对话框成功发布到用户的墙上,但这不是我想要的Play操作。

Here's a concise version of what I got so far, any help is much appreciated: 这是我到目前为止所获得的简洁版本,非常感谢您的帮助:

Couple Notes: I have a singleton FacebookInfo which takes care of handling Facebook delegates and stuff. 几个注意事项:我有一个单身的FacebookInfo ,负责处理Facebook委托和事物。 I also have a FacebookUser class which hold the current user's info for the current session, populated when calling me . 我还有一个FacebookUser类,用于保存当前会话的当前用户信息,并在致电给me时填充。 I also have a DLog method which simply does an NSlog only on debug mode. 我还有一个DLog方法,该方法仅在调试模式下才执行NSlog。

When a user clicks the Play button in my game, I would like to call my method [[Facebook sharedInfo] publishAction:@"play"] below. 当用户单击Play中的“ Play按钮时,我想在下面调用我的方法[[Facebook sharedInfo] publishAction:@"play"] I'm passing an NSString as action so later I can call the same method and use an action like Score and just modify the post accordingly. 我将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];
}

Wow, I know this is a long post, but I hope someone can help point me in the right direction. 哇,我知道这是一篇很长的文章,但是我希望有人可以帮助我指出正确的方向。

UPDATE 1: (2012/18/02) 更新1:(2012/18/02)

Ok. 好。 So I settled for making a page which contains the og meta-data which I did not want to do and supplied the url for my object. 因此,我决定制作一个页面,其中包含我不想做的og元数据,并为我的对象提供了url。 As per the FB Documentation, found here : 根据FB文档,可在此处找到:

Open Graph Mechanics

When users take an action in your app, such as cook the Stuffed Cookie, the app calls a Graph API to create a new cook action that connects the user with the Stuffed Cookie object. This is accomplished by issuing a HTTP POST to the user’s /me/myapp:cook connection with the URL of the recipe object. Facebook will then crawl the object URL, read the metadata, and connect the object to user's Graph via the action.

The diagram below illustrates the process:

User takes an action in the app, such as "cook" a "recipe"
App calls a Graph API /me/action:object=Object_URL
Facebook will crawl the object URL, read its meta tags and connects the object to the user's Graph via the action.

It would be cool if we can define these things in the app itself as params for cases where I do not need a website for. 如果我们可以在应用程序本身中将这些内容定义为我不需要网站的情况下的参数,那将很酷。

从2012年4月21日起,Facebook要求您创建一个页面来获取所需的数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM