我正在使用 FBSDKLoginKit 和 FBSDKShareKit 进行登录,然后共享 FBSDKShareOpenGraphContent。
我在 android 中有类似的行为,它工作正常。
我很快就能在 Facebook 上成功登录,但是当我调用 FBSDKShareDialog.show(from: self, with: content, delegate: nil) 从详细 View Controller 共享我的 FBSDKShareOpenGraphContent 时,应用程序显示登录 FACEBOOK 页面再次在浏览器中! 我还以为FBSDKShareOpenGraphContent是直接分享的,不需要重新登录!
如果 FBSDKAccessToken.currentAccessTokenIsActive() 返回 true,为什么会有这种行为? 如何在不同的 View Controller 之间保持相同的 session ? 我阅读了十亿篇关于它的帖子,但这些解决方案并没有解决我的问题
请注意,如果我第二次输入用户名和密码并重新登录,FBSDKShareOpenGraphContent 会正确共享! 但这是一种糟糕的用户体验,我希望用户只能登录 1 次!
请帮助 这是我的代码:
//APPDELEGATE
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
return true
}
private func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
}
private func application(application: UIApplication, openURL url: URL, sourceApplication: String?, annotation: Any?) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(
application,
open: url as URL?,
sourceApplication: sourceApplication,
annotation: annotation)
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
FBSDKAppEvents.activateApp()
}
----
//登录 VIEWCONTROLLER @IBAction
@IBAction func fbLoginButtonTapped(_ sender: UIButton) {
let fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
fbLoginManager.logIn(withReadPermissions: ["public_profile"], from: self) { (result, error) -> Void in
if (error == nil) {
let fbloginresult : FBSDKLoginManagerLoginResult = result!
// if user cancel the login
if (result?.isCancelled)! {
print("LOGIN FB CANCELLED")
return
}
if(fbloginresult.grantedPermissions.contains("public_profile")) {
print("LOGIN FB SUCCESS")
/* DO MY STUFF */
}
} else {
print("LOGIN FB ERROR")
}
}
}
//Page Detail ViewController with share button @IBAction
@IBAction func facebookButtonTapped(_ sender: UIButton) {
if (FBSDKAccessToken.currentAccessTokenIsActive() == true) {
//THIS RETURNS TRUE AS USER IS ALWAYS LOGGED
let properties = ["og:type": "article",
"og:title": "\(self.post?.title ?? "")",
"og:image": "\(self.post?.image ?? "")",
"og:description": "\(self.post?.content ?? "")"]
let object: FBSDKShareOpenGraphObject = FBSDKShareOpenGraphObject(properties: properties)
let action: FBSDKShareOpenGraphAction = FBSDKShareOpenGraphAction(type: "news.reads", object: object, key: "article")
let content: FBSDKShareOpenGraphContent = FBSDKShareOpenGraphContent()
content.action = action
content.previewPropertyName = "article"
FBSDKShareDialog.show(from: self, with: content, delegate: nil)
}
}
用于 Facebook 集成的 Info.plist
<!-- FBSDK INTEGRATION -->
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fb************</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>**************</string>
<key>FacebookDisplayName</key>
<string>*********</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbapi</string>
<string>fb-messenger-api</string>
<string>fbauth2</string>
<string>fbshareextension</string>
</array>
First Login page shown after login button tapped:
Login page again on share button tapped, after first login success
最佳答案
我用下面的代码解决了这个问题:
let shareDialog = FBSDKShareDialog()
shareDialog.delegate = self
shareDialog.shareContent = content
if (UIApplication.shared.canOpenURL( URL(string: "fbauth2:/")!) ) {
shareDialog.mode = .native
} else {
shareDialog.mode = .web
}
shareDialog.show()
我以前用过
shareDialog.mode = .auto
但是,如果它无法选择合适的操作或由于某种原因而失败,则似乎在不保持事件 session 的情况下重新实例化网络浏览器。
使用 .native 和 .web 模式,我可以处理安装或未安装 native 应用程序的情况,保持事件 session 。
关于ios - 保持相同的 session FBSDKLoginKit, FBSDKShareKit 4.36,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52343898/
我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
让多条路线去同一条路的最优雅的方式是什么ControllerAction?我有:get'dashboard',to:'dashboard#index'get'dashboard/pending',to:'dashboard#index'get'dashboard/live',to:'dashboard#index'get'dashboard/sold',to:'dashboard#index'这很丑陋。有什么“更优雅”的建议吗?一个类轮的奖励积分。 最佳答案 为什么不只有一个路由和一个Controller操作,并根据传递给它的参数来
print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上
在我的路线文件中我有:match'graphs/(:id(/:action))'=>'graphs#(:action)'如果是GET请求(工作)或POST请求(不工作),我想匹配它我知道我可以使用以下方法在资源中声明POST请求:post'/'=>:show,:on=>:member但是我怎样才能为比赛做到这一点呢?谢谢。 最佳答案 如果你同时想要POST和GETmatch'graphs/(:id(/:action))'=>'graphs#(:action)',:via=>[:get,:post]编辑默认值可以设置如下match'g
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:HowdoIgeneratealistofnuniquerandomnumbersinRuby?我想做的事:Random.rand(0..10).timesdoputsRandom.rand(0..10)end但如果随机数已经显示过,则无法再次显示。如何最轻松地做到这一点?
关闭。这个问题是off-topic.它目前不接受答案。想改进这个问题吗?Updatethequestion所以它是on-topic用于堆栈溢出。关闭11年前。Improvethisquestion我不经常使用ruby-通常它加起来相当于每两个月或更长时间编写一次脚本。我的大部分编程都是使用C++进行的,这与ruby有很大不同。由于我与ruby之间的差距如此之大,我总是忘记语言的基本方面(比如解析文本文件和其他简单的东西)。我想每天练习一些基本的东西,我想知道是否有一些我可以订阅的网站,并且会向我发送当天的Ruby问题或类似的东西。有人知道这样的站点/Internet服务吗?
如果我必须在一个HTTP请求中发送一堆post参数,所有这些参数都具有相同的名称,我该如何构建要发布的data对象?想象一个带有一些复选框的表单,它们都具有相同的name属性但具有不同的值(如果它们被选中):我想用ruby构建它(但它需要根据在表单上选择的内容动态创建):data={"color"=>"red","color"=>"green","color"=>"blue"}然后将数据发送到某个URL:Net::HTTP.post_form(url,data)我无法控制接收端,所以我必须发送它期望接收的参数。怎么办? 最佳答案