Dropbox Chooser unable to handle link ios swift - ios

I trying to implement Dropbox Chooser framework in my ios/swift projcet. Everything looks good. But I can't receive link when choose file from Dropbox. Only I see dialog with text "generating link" for a second in Dropbox app. Where is my problem? And sorry for my bad english.
Here is my button in my UIViewController:
func dropboxBtn(sender: AnyObject) {
// println("dropboxBtn")
let dbChooser = DBChooser(appKey: "drop-in-app-key")
dbChooser.openChooserForLinkType(DBChooserLinkTypePreview, fromViewController: self, completion: { (results: [AnyObject]!) -> Void in
println(results.description)
})
}
And here is my application function in AppDelegate.swift
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool {
println("openURL")
let dbChooser = DBChooser(appKey: "drop-in-app-key")
if (dbChooser.handleOpenURL(url)) {
return true
}
return false
}
I don't receive anything in the console...

I found my problem!
I forgot this configuration -> In the URL Schemes enter db-APP_KEY (replacing APP_KEY with the key generated when you created your app).
And now my methods is changed.
In my UIViewController:
func dropboxBtn(sender: AnyObject) {
DBChooser.defaultChooser().openChooserForLinkType(DBChooserLinkTypePreview, fromViewController: self, completion: { (results: [AnyObject]!) -> Void in
println(results.description)
})
}
In my AppDelegate.swift:
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool {
if (DBChooser.defaultChooser().handleOpenURL(url)) {
return true
}
return false
}

Related

Using TikTok's iOS Login kit with Flutter

I'm experimenting with adding TikTok authentication to my Flutter app (iOS only for now).
My first intention was to utilize TikTok's Login Kit for this and I started to look at how to call native iOS code from Flutter.
I have managed to set up the necessary piping in order to call the iOS code from Flutter but it's when I want to respond with a result I'm having issues.
The TikTok auth flow is initiated fine, I get taken to my TikTok App on my phone where I can authenticate or cancel and finally get redirected back to my app. As a result of this, I'm expecting the completion closure to be called, where I can report back the response to Flutter. This does not seem to happen.
Here's my AppDelegate.swift
#UIApplicationMain
#objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let channel = FlutterMethodChannel(name: "com.flutter.tiktok", binaryMessenger: controller as! FlutterBinaryMessenger)
channel.setMethodCallHandler { (methodCall : FlutterMethodCall, result : #escaping FlutterResult) -> Void in
if methodCall.method == "OpenTiktok"
{
let scopes = ["user.info.basic"]
let scopesSet = NSOrderedSet(array:scopes)
let request = TikTokOpenSDKAuthRequest()
request.permissions = scopesSet
request.state = "1234567890"
request.send(controller, completion: { (resp : TikTokOpenSDKAuthResponse) -> Void in
result(resp.code ?? "NO_CODE") // <-- THIS DOES NOT HAPPEN
})
}
}
GeneratedPluginRegistrant.register(with: self)
TikTokOpenSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
guard let sourceApplication = options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String,
let annotation = options[UIApplication.OpenURLOptionsKey.annotation] else {
return false
}
if TikTokOpenSDKApplicationDelegate.sharedInstance().application(app, open: url, sourceApplication: sourceApplication, annotation: annotation) {
return true
}
return false
}
override func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
if TikTokOpenSDKApplicationDelegate.sharedInstance().application(application, open: url, sourceApplication: sourceApplication, annotation: annotation) {
return true
}
return false
}
override func application(_ application: UIApplication, handleOpen url: URL) -> Bool {
if TikTokOpenSDKApplicationDelegate.sharedInstance().application(application, open: url, sourceApplication: nil, annotation: "") {
return true
}
return false
}
}
And here's how I'm triggering the message from Flutter:
Future<void> openTiktok() async {
try {
var code = await platform.invokeMethod("OpenTiktok");
setState(() {
_code = code;
});
} catch (e) {
print(e);
}
}
Appreciate any kind of feedback, thanks!
Got things to work finally and it had nothing to do with Flutter at all and was purely an iOS thing. Got some inspiration from this SO question.
What I had to do was to tweak the second application override.
The options dictionary seems to always be empty which caused the false return.
This is the final version of that application override:
override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any]) -> Bool {
if TikTokOpenSDKApplicationDelegate.sharedInstance().application(app, open: url, sourceApplication: nil, annotation: "") {
return true
}
return super.application(app, open: url, options: options)
}
Thanks

Getting null value while logging to Facebook to get users email ID swift 3

i was trying to get user's information by allowing users to login via facebook. I tried to get the information but instead it returns null value. Am i doing anything wrong ? i use a custom login button that i created. Below is my current code and i get "No information available".
#IBAction func fbLogin(_ sender: AnyObject) {
let fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
fbLoginManager.logIn(withReadPermissions: ["email"], from: self) { (result, error) -> Void in
if (error == nil){
let fbloginresult : FBSDKLoginManagerLoginResult = result!
if fbloginresult.grantedPermissions != nil {
if(fbloginresult.grantedPermissions.contains("email"))
{
self.getFBUserData()
}
}else {
print("No information available")
}
}
}
}
Below is my Appdelegate.swift code for fb
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
}
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, open: url as URL!, sourceApplication: sourceApplication, annotation: annotation)
}
func applicationDidBecomeActive(_ application: UIApplication) {
FBSDKAppEvents.activateApp()
}
}
I was finally able to get it working. I had to replace the below function
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, open: url as URL!, sourceApplication: sourceApplication, annotation: annotation)
}
with
func application(_ app: UIApplication, open url: URL, options: [String : AnyObject] = [:]) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(app,open: url,sourceApplication: options[UIApplicationOpenURLOptionsSourceApplicationKey] as! String,annotation: options [UIApplicationOpenURLOptionsAnnotationKey])
}
Once i changed it, i got the below error -
Optional(Error Domain=com.facebook.sdk.login Code=308 "(null)")
It looks like an issue with keychain and apple has changed the way of working in ios10. I referred the link - https://stackoverflow.com/a/38799196/6652247 and it worked. I was able to get the user information now.
Thanks Hoang Tran..

How to login with facebook in swift 2.0

I created a login with facebook application. At first i go to my profile and i created App ID and i added the bundled identifier. so, Simply I copied and past into the info.plist that was created on facebook with App ID and Bundle Identifier.Then I added FBSDKCoreKit.framework and FBSDKLoginKit.framework. And i added some codes. The problem is, Facebook login is successfully worked. But When i Press the Button Below error is printed and FBSDKLoginButtonDelegate functions not called. My system is Hackintosh Yosemite on Lenovo B460e. For reference please, see single line comments in code. Thanks you in advance.
Error:
2016-08-17 19:51:40.736 Facebook[925:34154] -canOpenURL: failed for URL: "fbauth2:/" - error: "(null)"
2016-08-17 19:51:40.808 Facebook[925:34154] -canOpenURL: failed for URL: "fbauth2:/" - error: "(null)"
Code i have try
info.plist
This is my AppDelegate.swift
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
return true
}
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation)
}
func applicationWillResignActive(application: UIApplication) {
}
func applicationDidEnterBackground(application: UIApplication) {
}
func applicationWillEnterForeground(application: UIApplication) {
}
func applicationDidBecomeActive(application: UIApplication) {
FBSDKAppEvents.activateApp()
}
func applicationWillTerminate(application: UIApplication) {
}
}
This is my View Controller.swift
import UIKit
class ViewController: UIViewController,FBSDKLoginButtonDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let loginButton: FBSDKLoginButton = FBSDKLoginButton()
loginButton.center = self.view.center
self.view!.addSubview(loginButton)
if (FBSDKAccessToken.currentAccessToken() != nil) {
print("Hello World!")
self.fetchProfile() //This function called and name,Id printed when the application opens initially that already logged in.
}
}
func fetchProfile()
{
print("Profile Fetched success fully")
let req = FBSDKGraphRequest(graphPath: "me", parameters: ["fields":"id,name"], tokenString: "accessToken.tokenString", version: nil, HTTPMethod: "GET")
req.startWithCompletionHandler({ (connection, result, error : NSError!) -> Void in
if(error == nil)
{
print("result \(result)")
}
else
{
print("error \(error)")
}
})
}
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String, annotation: AnyObject) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation)
}
func loginButton(loginButton: FBSDKLoginButton!, didCompleteWithResult result: FBSDKLoginManagerLoginResult!, error: NSError!) {
print("Hola") //This function not called when got name and ID
}
func loginButtonWillLogin(loginButton: FBSDKLoginButton!) -> Bool {
print("Hello") //This function not called when i log in
return true
}
func loginButtonDidLogOut(loginButton: FBSDKLoginButton!) {
print("Ni Hao") //This function not called when i log out
}
This has to do with the App Transport Security Settings of your application. Apple recently added extra security measures for arbitrary http loads. Try the following method:
Step 1: Go to your info.plist file
Step 2: Add a new key: "App Transport Security Settings"
Step 3: Add a boolean subkey, "Allow Arbitrary Loads", set it to YES
Step 4: Add a dictionary subkey, "Exception Domains"
Step 5: Add a string subkey to "Exception Domains" with the url causing you the error (fbauth2:/ in this case)
At the end, it should look like this (with your url of course)
As a side note, the Facebook SDK states that your application should still work, regardless of this warning (since you have added the correct entries to LSApplicationQueriesScheme). Did you make sure to assign the FB Login button's delegate to the receiving controller?

Handler does not get called after Facebook Browser Login redirects to Application

I am using Facebook SDK v4.8.0 for iOS in my application for login with Facebook. (iPhone OS version 9.3)
Following is some related code for integration:
AppDelegate.swift
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
return true
}
func applicationDidBecomeActive(application: UIApplication) {
FBSDKAppEvents.activateApp()
}
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation)
}
func application(application: UIApplication, openURL url: NSURL, options: [String: AnyObject]) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url,
sourceApplication: "UIApplicationOpenURLOptionsSourceApplicationKey",
annotation: "UIApplicationOpenURLOptionsAnnotationKey")
}
Login.Swift
#IBAction func btnFacebook(sender: UIButton) {
self.loginToFacebookWithSuccess({ (response) -> Void in
print("Success")
}) { (error) -> Void in
print("failure")
}
func loginToFacebookWithSuccess(successBlock: () -> (), andFailure failureBlock: (NSError?) -> ()) {
let fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
fbLoginManager.loginBehavior = .SystemAccount
FBSDKLoginManager().logInWithReadPermissions(["public_profile", "email", "user_friends"], fromViewController: self, handler: { (result:FBSDKLoginManagerLoginResult!, error:NSError!) -> Void in
if error != nil {
print("error")
} else if result.isCancelled {
print("cancelled")
} else {
print("worked fine") // get Facebook user data here
}
})
}
When the user has not configured Facebook account in the device, the App goes to browser and provides Facebook login UI. Once, the user is done with login the Browser redirects to the App. Till this point everything works fine.
Problem
When the browser redirects the user to App, nothing happens. (No handler for success OR failure is called). Just in case of user taps on "Done" in the browser, "cancelled" is printed in log. But, for "cancel" or "okay" (or say "Continue as Username") nothing happens after redirection.
Any clue?
Let me know, if I have missed any information.
I think your open url method needs following change:
func application(_ application: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey: Any]) -> Bool {
let isFBURL = ((url.scheme?.hasPrefix("fb\(FBSDKSettings.appID()!)"))! && url.host == "authorize")
if isFBURL == true {
return FBSDKApplicationDelegate.sharedInstance().application(application, open: url,
sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as? String,
annotation: options[UIApplicationOpenURLOptionsKey.annotation] as? String)
}
}
Let me know, if it works.
I'd recommend use Facebook approach and implement their FBSDKLoginButton. Set read permissions to the button facebookButton.readPermissions = ["email", "user_birthday", "public_profile"]. And the delegate to the viewController.
//MARK:- FBSDKLogin Button Delegate
extension LoginViewController: FBSDKLoginButtonDelegate {
func loginButton(loginButton: FBSDKLoginButton!, didCompleteWithResult result: FBSDKLoginManagerLoginResult!, error: NSError!) {
guard let response = result, let _ = response.token else {
createAlertController("Error", message: "There was a problem with the Facebook login. Please try again.")
return
}
//Do what ever you need here
}
func loginButtonDidLogOut(loginButton: FBSDKLoginButton!) {
//Required method, we don't need it at login screen
}
}
Make sure you follow all the Facebook plist settings information. And App Transport Security for iOS 9+
In the application(application: UIApplication, openURL url: NSURL, options: [String: AnyObject]) method you are passing in the sourceApplication and annotation parameters hardcoded strings.
I think that this is the issue. Try to pass the values that are in the options dictionary with the static keys UIApplicationOpenURLOptionsSourceApplicationKey and UIApplicationOpenURLOptionsAnnotationKey.
You also should need to add #available(iOS 9.0, *) before the method declaration because it's only available from iOS 9.
The final function should be something like this:
#available(iOS 9.0, *)
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(app, openURL: url, sourceApplication: options[UIApplicationOpenURLOptionsSourceApplicationKey] as! String, annotation: options[UIApplicationOpenURLOptionsAnnotationKey])
}

Open fully quitted app from URL scheme did not call the function from postNotificationName in iOS

Here I have set the code for URL scheme:
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
if let userUrl = String(url) as String? {
print("\(userUrl)")
if (userUrl == "count://fromClipBoard") {
NSNotificationCenter.defaultCenter().postNotificationName("com.getContentFromClipBoard", object: self)
}
}
return false
}
And add the following code to my ViewController:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "setContentFromClipBoard", name: "com.getContentFromClipBoard", object: nil)
//............
}
func setContentFromClipBoard() {
tv.text = "WAHAHA"
if let clipBoard = UIPasteboard.generalPasteboard().string {
tv.text = clipBoard
}
}
And when my app is not fully quitted, com.getContentFromClipBoard called well and tv.text become clipBoard.
However, when I fully quit the app and then use this URL scheme, the com.getContentFromClipBoard isn't get called and tv.text remain empty.
So how can I fix it? Thanks!
Fixed by checking UIApplicationLaunchOptionsURLKey too inside didFinishLaunchingWithOptions.
(Delaying is waiting the view to load)
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
if let userUrl = launchOptions?[UIApplicationLaunchOptionsURLKey] as? NSURL {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(2 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), {
if (userUrl.absoluteString == "count://fromClipBoard") {
NSNotificationCenter.defaultCenter().postNotificationName("com.getContentFromClipBoard", object: self)
}
})
}
}

Resources