Facebook SDK 集成 - 使用视图控制器而不是应用程序委托
正如标题所示,我现在发现自己正在使用新的 Facebook SDK——此处可用- - 在我的 iOS 应用程序中。
我已按照 Facebook 开发者网站上概述的此介绍进行操作,一切正常正如它应该的那样——至少根据它们的实施。
他们的做法意味着,在调用 applicationDidFinishLaunching 后,通过应用程序委托中的一系列方法和调用,用户可以选择将其帐户连接到应用程序。
相反,我只想在选择隐藏在应用程序其他位置的视图控制器中的按钮时强制执行此操作。也就是说,我不想在调用 applicationDidFinishLaunching 时处理授权 - 我希望在视图控制器中使用我自己的方法来强制授权。另外,我将从我自己的一些视图控制器中引用 Facebook 类,如果这有什么区别的话。
我已经进行了广泛的搜索,但尚未提出一个完全解释的解决方案(或任何东西,真的)来处理这个问题。如果有人对如何解决这个问题有想法,请告诉我。大多数情况下,StackOverflow 是最后的手段:)
编辑:正如下面提到的铍,我可以简单地将应用程序委托中的所有内容放入每个单独的视图控制器中。它有效,但这是处理这种独特情况的最佳方法还是有更好的实施方法?
谢谢,
相关代码如下:
sampleAppDelegate.h
@interface sampleAppDelegate : NSObject <UIApplicationDelegate,FBRequestDelegate, FBSessionDelegate, FBDialogDelegate, FBLoginDialogDelegate> {
Facebook *facebook;
}
@property (nonatomic, retain) Facebook *facebook;
@end
SampleAppDelegate.m
@synthesize facebook;
facebook = [[Facebook alloc] initWithAppId:@"102698856525645" andDelegate:self];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:@"FBAccessTokenKey"]
&& [defaults objectForKey:@"FBExpirationDateKey"]) {
facebook.accessToken = [defaults objectForKey:@"FBAccessTokenKey"];
facebook.expirationDate = [defaults objectForKey:@"FBExpirationDateKey"];
}
if (![facebook isSessionValid]) {
NSArray *permissions = [[NSArray alloc] initWithObjects:
@"offline_access",
@"publish_stream",
nil];
[facebook authorize:permissions];
[permissions release];
}
}
// For 4.2+ support
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [facebook handleOpenURL:url];
}
- (void)fbDidLogin {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[facebook accessToken] forKey:@"FBAccessTokenKey"];
[defaults setObject:[facebook expirationDate] forKey:@"FBExpirationDateKey"];
[defaults synchronize];
}
/*methods required by Facebook SDK to handle issues with connectivity--all currently empty*/
viewController.h
#import "FBConnect.h"
#import "sampleAppDelegate.h"
@class sampleAppDelegate;
@interface viewController : UIViewController <FBRequestDelegate> {
Facebook *facebook;
UnitedUpdatesAppDelegate *facebookSampleAppDelegate;
}
@property (nonatomic, retain) sampleAppDelegate *appDelegate;
@property (nonatomic, retain) Facebook *facebook;
viewController.m
-(void) facebookPost {
NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@"http://stackoverflow.com", @"link",
@"Message name", @"name",
@"Caption", @"caption",
@"Description", @"description",
@"Message", @"message",
nil];
[sampleAppDelegate dialog:@"feed" andParams:params andDelegate: sampleAppDelegate];
}
As the title suggests, I now find myself utilising the new Facebook SDK--available here-- within my iOS application.
I've followed this introduction outlined on the Facebook developer site, and everything works as it should--at least according to their implementation.
Their way of doing things means the user is presented with the choice to connect their account to the app after applicationDidFinishLaunching is called, via a series of methods and calls within the app delegate.
I would instead like to only force this upon the selection of a button within a view controller buried elsewhere in the app. That is, I don't want to deal with authorisation when applicationDidFinishLaunching is called--I want my own method in a view controller to force it. Also, I will be referencing the Facebook classes from a number of my own view controllers, if that makes any difference.
I've searched far and wide and have yet to come up with a fully explained solution (or anything at all, really) for dealing with this. If anyone has ideas about how to go about this, please let me know. StackOverflow is a last resort most of the time :)
Edit: As beryllium brought up below, I can simply take everything that is meant to be in the app delegate and slap it into each individual view controller. It works, but is this the best way to handle this unique situation or is there a better implementation to be had?
Thank you,
Relevant code below:
sampleAppDelegate.h
@interface sampleAppDelegate : NSObject <UIApplicationDelegate,FBRequestDelegate, FBSessionDelegate, FBDialogDelegate, FBLoginDialogDelegate> {
Facebook *facebook;
}
@property (nonatomic, retain) Facebook *facebook;
@end
sampleAppDelegate.m
@synthesize facebook;
facebook = [[Facebook alloc] initWithAppId:@"102698856525645" andDelegate:self];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:@"FBAccessTokenKey"]
&& [defaults objectForKey:@"FBExpirationDateKey"]) {
facebook.accessToken = [defaults objectForKey:@"FBAccessTokenKey"];
facebook.expirationDate = [defaults objectForKey:@"FBExpirationDateKey"];
}
if (![facebook isSessionValid]) {
NSArray *permissions = [[NSArray alloc] initWithObjects:
@"offline_access",
@"publish_stream",
nil];
[facebook authorize:permissions];
[permissions release];
}
}
// For 4.2+ support
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [facebook handleOpenURL:url];
}
- (void)fbDidLogin {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[facebook accessToken] forKey:@"FBAccessTokenKey"];
[defaults setObject:[facebook expirationDate] forKey:@"FBExpirationDateKey"];
[defaults synchronize];
}
/*methods required by Facebook SDK to handle issues with connectivity--all currently empty*/
viewController.h
#import "FBConnect.h"
#import "sampleAppDelegate.h"
@class sampleAppDelegate;
@interface viewController : UIViewController <FBRequestDelegate> {
Facebook *facebook;
UnitedUpdatesAppDelegate *facebookSampleAppDelegate;
}
@property (nonatomic, retain) sampleAppDelegate *appDelegate;
@property (nonatomic, retain) Facebook *facebook;
viewController.m
-(void) facebookPost {
NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@"http://stackoverflow.com", @"link",
@"Message name", @"name",
@"Caption", @"caption",
@"Description", @"description",
@"Message", @"message",
nil];
[sampleAppDelegate dialog:@"feed" andParams:params andDelegate: sampleAppDelegate];
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我相信这个 Facebook 代码不应该成为任何视图控制器的一部分。我更喜欢创建一个 Singleton 类来处理与 Facebook 的通信。该单例符合特定的接口,可以更方便地将其他服务(例如 Twitter)添加到应用程序中(每个服务可以由符合共享接口的单独单例处理)。
该接口可以定义诸如-login:、-logout:、-postMessage:之类的方法,即大多数服务共享的方法。
单例可以使用委托或块以类似的方式处理 Web 服务响应,例如,在委托实现的情况下,可以调用一些方法 -service:didSucceedWithStatus: 或 -service:didFailWithError: (其中 service 参数将指示发送委托消息的服务或单例实例的类型)。
实际上我确实根据上面的描述编写了一些代码,如果您感兴趣的话可以将其发布在这里。
I believe this Facebook code shouldn't be part of any view controller. I prefer to create a Singleton class to handle the communication with Facebook. This Singleton conforms to a certain interface, making it more convenient to add other services like Twitter to the app (each service could be handled by a separate singleton conforming to the shared interface).
The interface could define methods like -login:, -logout:, -postMessage:, i.e. methods shared by most services.
The singleton might use delegates or blocks to handle web service responses in a similar way, e.g. in case of a delegate implementation some methods could be called -service:didSucceedWithStatus: or -service:didFailWithError: (where the service parameter would indicate the type of service or singleton instance that sends the delegate message).
I actually did write some code according to the above description and could post it here if you're interested.
如果您询问是否可以甚至更好地在 AppDelegate 之外的其他地方使用委托方法,答案是“是”。
我的想法是准备一个包含 FB 的所有内容的类,并有一个可以触发登录和/或身份验证的按钮。
通常足以让您的控制器采用 FB 类所需的协议,并委托它来响应回调。
我尝试了类似的方法并且效果很好。
If You are asking if is possible or even better to use delegate methods in other places than AppDelegate, the answer is YES.
My idea is to prepare a class containing all the stuff for FB and have a button than can trigger the login and/ or authentication.
Usually is enough to make your controller adopt the protocols FB classes need, and delegate it to answer to callback.
I tried a similar approach and it works fine.