I'm a android developer and i'm new to Xcode and objective-c.
I'm using parse.com in my app and I'm trying to add the ability to login with face however, one of the headers of ParseFacebookUtils framework need the header FacebookSDK which is no more included in the new Facebook SDK.
Further investigation showed me that i need the FBSession header but i couldn't find it either.
Is there a solution for this? I'm using the newest Xcode, parse sdks and Facebook sdks.
EDIT:
[PFFacebookUtils logInInBackgroundWithReadPermissions:#[#"public_profile", #"user_about_me", #"user_friends", #"email"] block:^(PFUser *user, NSError *error) {
NSLog(#"Im here anyway!");
if (!user) {
NSLog(#"Uh oh. The user cancelled the Facebook login.");
} else if (user.isNew) {
NSLog(#"User signed up and logged in through Facebook!");
} else {
NSLog(#"User logged in through Facebook!");
}
}];
EDIT2:
//
// AppDelegate.m
// Listo
//
// Created by Amit Baz on 5/12/15.
// Copyright (c) 2015 Amit Baz. All rights reserved.
//
#import "AppDelegate.h"
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <FBSDKLoginKit/FBSDKLoginKit.h>
#import <ParseFacebookUtilsV4/PFFacebookUtils.h>
#import <Parse/Parse.h>
#interface AppDelegate ()
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[FBSDKLoginButton class];
[Parse setApplicationId:#""
clientKey:#""];
[PFFacebookUtils initializeFacebookWithApplicationLaunchOptions:launchOptions];
[PFAnalytics trackAppOpenedWithLaunchOptions:launchOptions];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// 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];
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
#end
Parse supports both v4.x and v3.x of the Facebook SDK. If you're using v4.x of the Facebook SDK, then instead of importing ParseFacebookUtils, you'll need to:
#import <ParseFacebookUtilsV4/PFFacebookUtils.h>
See https://www.parse.com/docs/ios/guide#fbusers for more info.
Delete FacebookSDK from
Build Phases-- > Link Binary With Libraries Delete FacebookSDK.framework
Add the FacebookSDK framework again
Looks like the Facebook SDK had a major update in v4.0 that split it up into multiple frameworks. Until parse is updated to work with the new SDK, you'll have to download and use a v3.x or lower version of the Facebook SDK.
Related
This is a repeat I believe of unanswered question here:
https://stackoverflow.com/questions/34499353/could-not-build-module-parse-xcode-6-1-1
I have attempted uninstall and reinstall the sdks, remove and reinsert the framework, and reinstalled the framework and sdk into a brand new project, and is giving error message Every time I try to add reference in AppDelegate.m by adding #import it says couldn't build module 'Parse'.Here are the steps I have followed : https://parse.com/apps/quickstart#parse_data/mobile/ios/native/existing.
Please help me to understand where I went wrong, any feedback would be highly appreciated.
AppDelegate.m
#import "AppDelegate.h"
#import <Parse/Parse.h>
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
// [Optional] Power your app with Local Datastore. For more info, go to
// https://parse.com/docs/ios/guide#local-datastore
[Parse enableLocalDatastore];
// Initialize Parse.
[Parse setApplicationId:#"Removed for security purposes"
clientKey:#"Removed for security purposes"];
// [Optional] Track statistics around application opens.
[PFAnalytics trackAppOpenedWithLaunchOptions:launchOptions];
// Register for Push Notitications
UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge |
UIUserNotificationTypeSound);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes
categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
//Starting the ROXIMITY Engine!
[ROXIMITYEngine startWithLaunchOptions:launchOptions engineOptions:nil applicationId:#"Removed for security purposes" andEngineDelegate:self];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
[ROXIMITYEngine resignActive]; // Place in applicationWillResignActive
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
[ROXIMITYEngine background]; // Place in applicationDidEnterBackground
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
[ROXIMITYEngine foreground]; // Place in applicationWillEnterForeground
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// 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.
[ROXIMITYEngine active]; // Place in applicationDidBecomeActive
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
[ROXIMITYEngine terminate]; // Place in applicationWillTerminate
}
//Adding the following methods for remote notification handling
-(void) application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
[ROXIMITYEngine didFailToRegisterForRemoteNotifications:error];
}
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[ROXIMITYEngine didRegisterForRemoteNotifications:deviceToken];
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation setDeviceTokenFromData:deviceToken];
currentInstallation.channels = #[#"global"];
[currentInstallation saveInBackground];}
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
[ROXIMITYEngine didReceiveRemoteNotification:application userInfo:userInfo];
[PFPush handlePush:userInfo];
if (application.applicationState == UIApplicationStateInactive) {
[PFAnalytics trackAppOpenedWithRemoteNotificationPayload:userInfo];
}
}
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
[ROXIMITYEngine didReceiveLocalNotification:application notification:(UILocalNotification *)notification];
}
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
[ROXIMITYEngine didReceiveRemoteNotification:application userInfo:userInfo fetchCompletionHandler:completionHandler];
if (application.applicationState == UIApplicationStateInactive) {
[PFAnalytics trackAppOpenedWithRemoteNotificationPayload:userInfo];}
}
#end
AppDelegate.h
#import <UIKit/UIKit.h>
#import "ROXIMITYSDK.h"
#interface AppDelegate: UIResponder <UIApplicationDelegate, ROXIMITYEngineDelegate>
#property (strong, nonatomic) UIWindow *window;
#end
I ran into this problem as well when trying to integrate the SDK manually. I solved it by using cocoapods to handle integrating Parse.
I was following Facebook's own tutorial for FB login in iOS (Objective-C) but every time I log in - after the initial permission authorization screen - I'm getting the infamous "You have already authorized this app" webview.
I've read a ton of posts but I haven't been able to sort it out, hence the (re)post. I find this rather odd because the app has absolutely nothing except the boilerplate login code. This behaviour happens in both Simulator and real devices.
This app is for iOS 9.0 and I am using FBSDK 4.7.1 (installed via CocoaPods):
pod 'FBSDKLoginKit', '~> 4.6'
The code itself is pretty boilerplate stuff, here's my AppDelegate.m:
#import "AppDelegate.h"
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#interface AppDelegate ()
#end
#implementation AppDelegate
- (void)applicationDidBecomeActive:(UIApplication *)application {
[FBSDKAppEvents activateApp];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
return YES;
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
#end
and my ViewController.m:
#import "ViewController.h"
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <FBSDKLoginKit/FBSDKLoginKit.h>
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
FBSDKLoginButton *loginButton = [[FBSDKLoginButton alloc] init];
loginButton.readPermissions = #[#"public_profile", #"email", #"user_friends"];
[loginButton setLoginBehavior:FBSDKLoginBehaviorSystemAccount]; // No difference
loginButton.center = self.view.center;
[self.view addSubview:loginButton];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
And a screenshot of the Info.plist:
Finally, I'm also getting these two errors in the console:
2015-11-24 11:50:42.855 lixo[26941:389756] -canOpenURL: failed for URL: "fbauth2:/" - error: "(null)"
2015-11-24 11:50:42.860 lixo[26941:389756] -canOpenURL: failed for URL: "fbauth2:/" - error: "(null)"
Although from what I've read this can be safely ignored if LSApplicationQueriesSchemes is set in the Info.plist.
Any ideas how to avoid this?
Instead of triggering a login on every launch, you can check the status of the access token. If it's not expired, you skip login, and just start using the API. The following method can be used to check if the token is expired:
+(BOOL) accessTokenIsLocalyValid
{
return [FBSDKAccessToken currentAccessToken] && [[NSDate date] compare:[FBSDKAccessToken currentAccessToken].expirationDate] == NSOrderedAscending;
}
If you have a valid token, you can refresh it using [FBSDKAccessToken refreshCurrentAccessToken:].
Check if there is a current session before logging in with FBSDKLoginManager.
if ([FBSDKAccessToken currentAccessToken])
{
NSLog(#"Token is available : %#",[[FBSDKAccessToken currentAccessToken]tokenString]);
// Now get details using graphpath.
} else {
// login with permissions using FBSDKLoginManager and get details using graphpath in completion
}
This is the default behaviour!
Facebook SDK allows you to login to facebook from Facebook App (if it is installed in your phone), OR else it will manage the login from Safari.
And when Facebook login is used by your application from Safari, this is how you have to accept permission everytime.
Another behaviour is that If your iphone doesnt have Facebook App, and you use Facebook SDK login process from your application, it will use Safari; you wont be able to logout even, as Safari saves your credentials in cookies and there is no way by which you can clear safari cookies from your application.
If your phone has Facebook App, it will redirect to your application without any interruptions as such.
EDIT -
This behaviour is also found in iOS 10.
Thanks for the edit - Tiois
I have a viewController which shows a FB button for signing up and taking the user to the next viewController.
I have made changes in info.plist
AppDelegate.m
#import "AppDelegate.h"
#import <Parse/Parse.h>
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <FBSDKLoginKit/FBSDKLoginKit.h>
#import <ParseFacebookUtilsV4/PFFacebookUtils.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// Initialize Parse.
[Parse setApplicationId:#"PARSE_APP_ID"
clientKey:#"PARSE_CLIENT_KEY"];
[PFFacebookUtils initializeFacebookWithApplicationLaunchOptions:launchOptions];
[FBSDKLoginButton class];
// [Optional] Track statistics around application opens.
[PFAnalytics trackAppOpenedWithLaunchOptions:launchOptions];
// return [[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
return YES;
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[FBSDKAppEvents activateApp];
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
StoryBoard
Add a UIButton and change the class to FBSDKLoginButton
Add a Segue from this UIButton to next ViewController and name it as FBSegue
Add IBAction from this UIButton and call it as fbLoginAction
loginViewController.m
#import "LoginViewController.h"
#import <Parse/Parse.h>
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <FBSDKLoginKit/FBSDKLoginKit.h>
#import <ParseFacebookUtilsV4/PFFacebookUtils.h>
- (IBAction)fbLoginAction:(id)sender {
[self fbLogin];
}
- (void)fbLogin {
NSArray *permissions = #[#"public_profile", #"email"];
[PFFacebookUtils logInInBackgroundWithReadPermissions:permissions block:^(PFUser *user, NSError *error) {
if (!user) {
NSLog(#"Uh oh. The user cancelled the Facebook login.");
} else if (user.isNew) {
NSLog(#"User signed up and logged in through Facebook!");
[self performSegueWithIdentifier:#"FBSegue" sender: self];
} else {
NSLog(#"User logged in through Facebook!");
[self performSegueWithIdentifier:#"FBSegue" sender: self];
}
}];
}
Problems
When I click Login With Facebook button on iOS Simulator, I get Safari page to authorize app. When I do that, I still see loginViewController with the facebook button changed to Logout.
When I click Logout button, I am taken to facebook on Safari with message that I have already authorized the app and then I am taken back to my app. There is option in bottom for Logout and Cancel, but in clicking either, I am taken to the next View Controller.
Any guidance please? I understand that since I have not done anything under viewDidLoad method, my user won't be logged in and taken to next View Controller when the app starts.
I think you are using FBSDKLoginButton in the wrong way.
From the documentation on https://developers.facebook.com/docs/reference/ios/current/class/FBSDKLoginButton/
FBSDKLoginButton works with [FBSDKAccessToken currentAccessToken] to
determine what to display, and automatically starts authentication
when tapped (i.e., you do not need to manually subscribe action
targets).
So you shouldn't have to use IBAction and you can do by using UIView instead of UIButton for FBSDKLoginButton
I followed google developer docs to implement a simple google plus (gmail) sign in button in my basic app. But When i run the code it going to google.com.
So here are the steps i followed.
1.Created new client id and added that into app from google console.
2.Imported frameworks
3.When i run the code i can see
it first open google sign in page then it will open Oauth page if i press "allow" access then it will redirect from "accounts.google.com" to "google.com.
I have created a sample project for that
Here is my code and screen shots
my file and framework list
CODE
AppDelegate.m
#import <GooglePlus/GooglePlus.h>
#import "AppDelegate.h"
#interface AppDelegate ()
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (BOOL)application: (UIApplication *)application
openURL: (NSURL *)url
sourceApplication: (NSString *)sourceApplication
annotation: (id)annotation {
return [GPPURLHandler handleURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
ViewController.h
#import <UIKit/UIKit.h>
#import <GooglePlus/GooglePlus.h>
#class GPPSignInButton;
#interface ViewController : UIViewController<GPPSignInDelegate>
#property (strong, nonatomic) IBOutlet GPPSignInButton *signInButton;
#end
ViewController.m
//
#import <GooglePlus/GooglePlus.h>
#import "ViewController.h"
#import <GoogleOpenSource/GoogleOpenSource.h>
#define kClientId #"49781846815-pbsb1vso4nrbes9a4al5kae2d98ie3cf.apps.googleusercontent.com"
#define kGTLAuthScopePlusLogin #"https://www.googleapis.com/auth/plus.login"
#interface ViewController ()
#end
#implementation ViewController
#synthesize signInButton;
- (void)viewDidLoad {
[super viewDidLoad];
GPPSignIn *signIn = [GPPSignIn sharedInstance];
// Do any additional setup after loading the view, typically from a nib.
signIn.shouldFetchGooglePlusUser = YES;
signIn.shouldFetchGoogleUserEmail = YES; // Uncomment to get the user's email
// You previously set kClientId in the "Initialize the Google+ client" step
signIn.clientID = kClientId;
// Uncomment one of these two statements for the scope you chose in the previous step
signIn.scopes = #[ kGTLAuthScopePlusLogin ]; // "https://www.googleapis.com/auth/plus.login" scope
signIn.scopes = #[ #"profile" ]; // "profile" scope
// Optional: declare signIn.actions, see "app activities"
signIn.delegate = self;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)finishedWithAuth: (GTMOAuth2Authentication *)auth
error: (NSError *) error {
NSLog(#"Received error %# and auth object %#",error, auth);
if (error) {
// Do some error handling here.
} else {
[self refreshInterfaceBasedOnSignIn];
}
}
-(void)refreshInterfaceBasedOnSignIn {
if ([[GPPSignIn sharedInstance] authentication]) {
// The user is signed in.
NSLog(#"hi");
self.signInButton.hidden = YES;
// Perform other actions here, such as showing a sign-out button
} else {
self.signInButton.hidden = NO;
// Perform other actions here
}
}
- (void)presentSignInViewController:(UIViewController *)viewController {
// This is an example of how you can implement it if your app is navigation-based.
[[self navigationController] pushViewController:viewController animated:YES];
}
#end
Please help to clear this google.com redirect issue and also to develop a good login.
As of May 2015, even if you got this working, your app would then be rejected by Apple's App Store review team because of a childish fight going on between Apple and Google. See this issue in the Google+ SDK: https://code.google.com/p/google-plus-platform/issues/detail?id=900
#import "AppDelegate.h"
#import "Scringo/scringo.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
return YES;
[Scringo initWithAppId:#"" completion:nil];
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
--
Is this the correct spot? the sidebar doesn't slide out in the emulator and I'm not getting any errors?… help
Use before return statement,
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[Scringo initWithAppId:#"YOUR_SCRINGO_APP_ID" completion:nil];
// Override point for customization after application launch.
return YES;
}