How to login and request extended permission in a single call? - iphone

OK, so I need my app to be able to post something on the users's wall but I'm not very happy with the solution of showing the login pop-up and then the extended permission request popup.
Can it be done with only one popup? Or even with 2 pop-ups but triggered by a single API call?

It might help -
- (void)viewDidLoad {
FacebookAPIAppDelegate *appDelegate =(FacebookAPIAppDelegate *)[[UIApplication sharedApplication]delegate];
if (appDelegate._session == nil){
appDelegate._session = [FBSession sessionForApplication:_APP_KEY
secret:_SECRET_KEY delegate:self];
}
if(self.loginButton == NULL)
self.loginButton = [[[FBLoginButton alloc] init] autorelease];
loginButton.frame = CGRectMake(0, 0, 200, 50);
[self.view addSubview:loginButton];
[super viewDidLoad];
}
- (void)session:(FBSession*)session didLogin:(FBUID)uid {
self.usersession =session;
NSLog(#"User with id %lld logged in.", uid);
[self getFacebookName];
}
- (void)getFacebookName {
NSString* fql = [NSString stringWithFormat:
#"select uid,name from user where uid == %lld", self.usersession.uid];
NSDictionary* params = [NSDictionary dictionaryWithObject:fql forKey:#"query"];
[[FBRequest requestWithDelegate:self] call:#"facebook.fql.query" params:params];
self.post=YES;
}
- (void)request:(FBRequest*)request didLoad:(id)result {
if ([request.method isEqualToString:#"facebook.fql.query"]) {
NSArray* users = result;
NSDictionary* user = [users objectAtIndex:0];
NSString* name = [user objectForKey:#"name"];
self.username = name;
if (self.post) {
[self postToWall];
self.post = NO;
}
}
}
- (void)postToWall {
FBStreamDialog *dialog = [[[FBStreamDialog alloc] init] autorelease];
dialog.userMessagePrompt = #"Enter your message:";
//dialog.attachment = [NSString stringWithFormat:#"{\"name\":\"Check this Mix\",\"href\":\"http://developers.facebook.com/connect.php?tab=iphone\",\"caption\":\"Caption\",\"description\":\"Description\",\"media\":[{\"type\":\"image\",\"src\":\"http://img40.yfrog.com/img40/5914/iphoneconnectbtn.jpg\",\"href\":\"http://developers.facebook.com/connect.php?tab=iphone/\"}],\"properties\":{\"another link\":{\"text\":\"Facebook home page\",\"href\":\"http://www.facebook.com\"}}}"];
dialog.attachment = [NSString stringWithFormat:#"{\"name\":\"Check this Mix\",\"href\":\"http://developers.facebook.com/connect.php?tab=iphone\",\"caption\":\"Caption\",\"media\":[{\"type\":\"image\",\"src\":\"http://img40.yfrog.com/img40/5914/iphoneconnectbtn.jpg\",\"href\":\"http://developers.facebook.com/connect.php?tab=iphone/\"}],\"properties\":{\"another link\":{\"text\":\"Facebook home page\",\"href\":\"http://www.facebook.com\"}}}"];
[dialog show];
}

as long as the user has logged in and granted permissions once, he should not need to do so again. here's the code I use:
//these to need to be declared in .h
NSString * currentRequest;
BOOl hasAskedForPermissions;
FBSession * mySession
//then in .m
#synthesize currentRequest
#synthesize hasAskedForPermissions
-(void)viewDidLoad {
static NSString* kApiKey = #"XXXXXXXXXXXXXXXXXXXXXXX";
static NSString* kApiSecret = #"XXXXXXXXXXXXXXXXXXXXXXXXXX";
mySession = [[FBSession alloc] initWithKey:kApiKey secret:kApiSecret getSessionProxy:nil];
}
-(void)resumeConnection {
NSLog(#"resuming connection");
static NSString* kApiKey = #"XXXXXXXXXXXXXXXXXXXXXXX";
static NSString* kApiSecret = #"XXXXXXXXXXXXXXXXXXXXXXXXXX";
if ([mySession resume]) {
}
else {
NSLog(#"session did not resume successfully");
mySession = [[FBSession sessionForApplication:kApiKey
secret:kApiSecret delegate:self] retain];
_loginDialog = [[FBLoginDialog alloc] init];
[_loginDialog show];
}
}
-(void)postStatus {
currentRequest = #"post status";
//NSLog(#"current request: %#", currentRequest);
if (!(mySession.isConnected)) {
[self resumeConnection];
}
else if (mySession.isConnected) {
NSLog(#"session is connected");
//Add your posting code here.
} else {
NSLog(#"session is not connected, did not connect");
}
}
-(void)loadPermissionDialog {
FBPermissionDialog* dialog = [[FBPermissionDialog alloc] initWithSession:_session];
dialog.delegate = self;
dialog.permission = #"read_stream, publish_stream, read_friendlists";
[dialog show];
}
- (void)session:(FBSession *)session didLogin:(FBUID)uid {
NSLog(#"Session Logged in sucessfully");
//NSLog(#"current request: %#", currentRequest);
mySession = session;
if (hasAskedForPermissions) {
if ([currentRequest isEqualToString:#"post status"]) {
[self postStatus];
}
}
else {
NSLog(#"asking for permissions");
hasAskedForPermissions = YES;
//you should save this in UserDefaults and recall it in viewDidLoad
[self loadPermissionDialog];
}
}
I don't know how to actually do the post request, but if you run this code the user should only have to log in and assign permissions once.

Related

FBLoginView not responding

While I'm am trying FBLoginView is not working. The button is not even shown any response while clicked. This is the code which I used:
#import <FacebookSDK/FacebookSDK.h>
#interface myaccount ()<FBLoginViewDelegate>
- (void)viewDidLoad
{
FBLoginView *loginview =[[FBLoginView alloc] init];
loginview.frame = btn1.frame;
for (id obj in loginview.subviews)
{
if ([obj isKindOfClass:[UIButton class]])
{
btn1 = obj;
[btn1 setBackgroundColor:UIColorFromRGB(0x3b5999)];
[btn1 sizeToFit];
}
}
loginview.delegate = self;
[scrol addSubview:loginview];
- (void)loginViewFetchedUserInfo:(FBLoginView *)loginView
user:(id<FBGraphUser>)user
{
logu.name = [NSString stringWithFormat:#"%#!", user.first_name];
logu.profilePic.profileID = user.id;
profilePicker.profileID = user.id;
self.loggedInUser = user;
}
}
Please help me to sort it out?
you can implement facebook in your application via using Graph Api .
create object of Graph api and set permission like
NSString *client_id = #"124262614407976";
if(reachabilityFlags==TRUE)
{
#try {
self.fbGraph = [[FbGraph alloc] initWithFbClientID:client_id];
[self.fbGraph authenticateUserWithCallbackObject:self
andSelector:#selector(fbGraphCallback:) andExtendedPermissions:#"user_photos,user_videos,
publish_stream,offline_access,user_checkins,
friends_checkins" andSuperView:self.window];
}
#catch (NSException *exception) {
// NSLog(#"Net not available %#",exception.userInfo);
}
#finally {
}
}
-- After it check call back.
- (void)fbGraphCallback:(id)sender
{
if ( (fbGraph.accessToken == nil) || ([fbGraph.accessToken length] == 0) ) {
NSLog(#"You pressed the 'cancel' or 'Dont Allow' button, you are NOT logged into Facebook...I require you to be logged in & approve access before you can do anything useful....");
//restart the authentication process.....
[fbGraph authenticateUserWithCallbackObject:self andSelector:#selector(fbGraphCallback:)
andExtendedPermissions:#"user_photos,user_videos,publish_stream,offline_access,user_checkins,friends_checkins"];
} else
{
// NSLog(#"------------>CONGRATULATIONS<------------, You're logged into Facebook... Your oAuth token is: %#", fbGraph.accessToken);
}
}
//////// you can find friend feed ..
-(void)getMeFeedButtonPressed{
if(delegate.fbGraph.accessToken!=nil)
{
NSString *customString=[NSString stringWithFormat:#"me"];
NSLog(#"here responce is for %#",customString);
FbGraphResponse *fb_graph_response = [delegate.fbGraph doGraphGet:customString withGetVars:nil];
NSLog(#"getMeFeedButtonPressed: %#", fb_graph_response.htmlResponse);
//parse our json
SBJSON *parser = [[SBJSON alloc] init];
NSDictionary *facebook_response = [parser objectWithString:fb_graph_response.htmlResponse error:nil];
// [facebook_response ]
[parser release];
// MyID=[facebook_response objectForKey:#"id"] ;
[MyID appendString:[facebook_response objectForKey:#"id"]];
NSLog(#"name %#",[facebook_response objectForKey:#"name"]);
NSString * url = [NSString stringWithFormat:#"https://graph.facebook.com/%#/picture",MyID];
NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
UIImage *downloadedImage = [UIImage imageWithData:data];
NSData *myEncodedImages = [NSKeyedArchiver archivedDataWithRootObject:downloadedImage];
[[NSUserDefaults standardUserDefaults ] setObject:myEncodedImages forKey:#"MYFBIMAGE"];
[self postData];
}else
{
#try {
[delegate.fbGraph authenticateUserWithCallbackObject:self andSelector:#selector(fbGraphCallback:)
andExtendedPermissions:#"user_photos,user_videos,publish_stream,offline_access,user_checkins,friends_checkins,email"];
}
#catch (NSException *exception) {
NSLog(#"Net not available");
}
#finally {
}
}
}

Post to Facebook not working from delegate

I have added FBSdk in my project along with SBJson classes, what files should i import in my second view controller to work my code ?
I want to post on Fb using the description under url so for that i need to include this code into my second view controller, but i am stuck in a part i founded that the below code should be added in the second view controller but the "delegate:self" not works, as i am doing this first time so can any one guide me how should i code in my second view controller keeping into account the values from the app delegate (How should i get the values from the app delegate of FB to the second view so that i can add this code in second code plz can any one correct this code)
facebook = [[Facebook alloc] initWithAppId:#"YOUR_APP_ID"];
// how should i take this id from the app delegate ?
NSArray* permissions = [NSArray arrayWithObjects:#"read_stream",
#"publish_stream", nil];
[facebook authorize:permissions delegate:self];
NSMutableDictionary* params = [[NSMutableDictionary alloc]
initWithCapacity:1]
[params setObject:#"Testing" forKey:#"name"];
[params setObject:#"IMAGE_URL" forKey:#"picture"];
[params setObject:#"Description" forKey:#"description"];
[facebook requestWithGraphPath:#"me/feed"
andParams:params
andHttpMethod:#"POST"
andDelegate:self];
Is the above code correct ?
How should i implement it in my second view controller in -(void)fb_share (method).
My App Delegate File is Like this :
#import "AppDelegate.h"
#import "ViewController.h"
#import "ServerRequests.h"
#import "DBManager.h"
#import "SBJson.h"
#include "FBSession.h"
#import "FBRequest.h"
#import "FBGraphUser.h"
NSString *const FBSessionStateChangedNotification = #"com.myapp:FBSessionStateChangedNotification";
#implementation AppDelegate
#synthesize userId;
#synthesize dbSnyced;
#synthesize fbId;
#synthesize loginView;
- (void)dealloc
{
[_window release];
[_viewController release];
[super dealloc];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{ self.fbId = #"-1";
self.dbSnyced = NO;
self.loginView = nil;
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.viewController = [[[ViewController alloc] initWithNibName:#"ViewController" bundle:nil] autorelease];
self.navigationController = [[[UINavigationController alloc] initWithRootViewController:self.viewController] autorelease];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
if (![self openSessionWithAllowLoginUI:NO]) {
[self showLogin:NO];
}
return YES;
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[self checkAccountLogin];
}
- (void) applicationDidEnterBackground:(UIApplication *)application
{
[self hideLogin:NO];
}
- (void) applicationWillTerminate:(UIApplication *)application
{
NSLog(#"applicationWillTerminate");
[self hideLogin:NO];
[FBSession.activeSession close];
}
- (void) checkAccountLogin
{
self.dbSnyced = NO;
if([ServerRequests serverIsReachableAlertIfNo:YES]) {
DBManager *db = [[[DBManager alloc] initWithPath:DB_NAME] autorelease];
NSDictionary *userDic = [[db smartQueryForArrayWithStatement:#"SELECT * FROM table WHERE id=1"] objectAtIndex:0];
NSString *loginType = [userDic objectForKey:#"login_type"];
if([loginType isEqualToString:#"none"]) {
NSLog(#"no login type");
[self showLogin:NO];
}
else {
self.userId = [[userDic objectForKey:#"user_id"] intValue];
if([loginType isEqualToString:#"Facebook"]) {
NSLog(#"Facebook account");
[FBSession.activeSession handleDidBecomeActive];
}
else if([loginType isEqualToString:#"MyApp"]) {
NSLog(#"MyApp account");
}
}
}
}
#pragma - Fb stuff
/*
* Callback for session changes.
*/
- (void)sessionStateChanged:(FBSession *)session state:(FBSessionState) state error:(NSError *)error
{
NSLog(#"sessionStateChanged");
switch (state) {
case FBSessionStateOpen:
if (!error) {
[self handleFbUserDetails];
}
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
[FBSession.activeSession closeAndClearTokenInformation];
break;
default:
break;
}
[[NSNotificationCenter defaultCenter] postNotificationName:FBSessionStateChangedNotification object:session];
if (error) {
NSLog(#"error: %#", error.localizedDescription);
if(self.loginView) {
[self.loginView hideLoading];
}
}
}
/*
* Opens a Facebook session and optionally shows the login UX.
*/
- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI {
return [FBSession openActiveSessionWithReadPermissions:nil
allowLoginUI:allowLoginUI
completionHandler:^(FBSession *session,
FBSessionState state,
NSError *error) {
[self sessionStateChanged:session
state:state
error:error];
}];
}
/*
* If we have a valid session at the time of openURL call, we handle
* Facebook transitions by passing the url argument to handleOpenURL
*/
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
// attempt to extract a token from the url
return [FBSession.activeSession handleOpenURL:url];
}
- (BOOL) activeFBSession
{
return FBSession.activeSession.isOpen;
}
- (void) closeFBSession
{
NSLog(#"closeFBSession");
[FBSession.activeSession closeAndClearTokenInformation];
}
- (void) showLogin:(BOOL)animated
{
if(!self.loginView) {
self.loginView = [[[LoginViewController alloc] init] autorelease];
[[self.navigationController topViewController] presentViewController:self.loginView animated:animated completion:nil];
}
}
- (void) hideLogin:(BOOL)animated
{
if(self.loginView) {
[self.viewController gotToTab:0];
[self.loginView hideLoading];
[[self.navigationController topViewController] dismissViewControllerAnimated:animated completion:^{
self.loginView = nil;
NSLog(#"self.loginView = nil");
}];
}
}
- (void) handleFbUserDetails
{
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (!error) {
NSLog(#"fb connected");
self.fbId = [user objectForKey:#"id"];
self.userId = -1;
ASIFormDataRequest *request = [ServerRequests ASIFormDataRequestForSrcipt:#"facebookUser"];
[request setPostValue:[user objectForKey:#"id"] forKey:#"fbId"];
[request setPostValue:user.first_name forKey:#"first_name"];
[request setPostValue:user.last_name forKey:#"last_name"];
[request setPostValue:user.location.name forKey:#"location"];
[request setCompletionBlock:^{
NSString *response = [request responseString];
NSLog(#"facebookUser response: %#", response);
if([response rangeOfString:#"ERROR"].location == NSNotFound) {
self.userId = [response intValue];
DBManager *db = [[DBManager alloc] initWithPath:DB_NAME];
NSString *q = [NSString stringWithFormat:#"UPDATE table SET login_type = 'Facebook', user_id = '%#' WHERE id = 1", response];
NSLog(#"%#", q);
[db executeStatement:q];
[db release];
}
else {
}
[self sessionBecameActive];
}];
[request startAsynchronous];
[self hideLogin:YES];
}
else {
NSLog(#"error: %#", error.localizedDescription);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Facebook Request Error" message:#"Cannot connect to Facebook." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
alert.delegate = self;
[alert show];
[alert release];
if(self.loginView) {
[self.loginView hideLoading];
}
}
[ServerRequests SyncDataBase];
}];
}
- (void) signOut
{
[self closeFBSession];
DBManager *db = [[DBManager alloc] initWithPath:DB_NAME];
[db executeStatement:#"UPDATE table SET login_type = 'none' WHERE id = 1"];
[db release];
[self showLogin:YES];
}
- (void) sessionBecameActive
{
[self.viewController sessionBecameActive];
}
#end
Can any one figure out what code should i write in the -(void)fb_share method in second view controller by getting values from the delegate ?
Any Help !
I did this ... and getting Error: HTTP status code: 400 ... but the user name get's displayed on alert
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (!error) {
// NSArray* permissions = [NSArray arrayWithObjects:#"read_stream",
// #"publish_stream", nil];
// [facebook authorize:permissions delegate:self];
self.params = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
#"https://developers.facebook.com/ios", #"link",
#"https://developers.facebook.com/attachment/iossdk_logo.png", #"picture",
#"Facebook SDK for iOS", #"name",
#"Build great social apps and get more installs.", #"caption",
#"The Facebook SDK for iOS makes it easier and faster to develop Facebook integrated iOS apps.", #"description",
nil];
UIAlertView *tmp = [[UIAlertView alloc]
initWithTitle:#"Upload to FB?"
message:[NSString stringWithFormat:#"Upload to ""%#"" Account?", user.name]
delegate:self
cancelButtonTitle:nil
otherButtonTitles:#"No",#"Yes", nil];
[FBRequestConnection startWithGraphPath:#"me/feed"
parameters:self.params
HTTPMethod:#"POST"
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
UIAlertView *tmp = [[UIAlertView alloc]
initWithTitle:#"Success"
message:#"PostUploaded"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:#"Ok", nil];
[tmp show];
[tmp release];
}
}];
[tmp show];
[tmp release];
}
}];
.. what should i do now ?
declare facebook as a property in .h file of your appDelegate
then in second view controller import AppDelegate
in .m file where you want the Facebook object
get it like
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
Facebook *facebook = appDelegate.facebook;

Advertisements not removed after IAP unless app is restarted?

In my app, there is code that, if a button is pressed the user can upgrade the app and remove the advertisements, it calls the MKStoreKit and once the user purchases the upgrade, the adverts do remain in the app UNTIL the app is restarted.
I want to fix this, so the advertisements are removed immediately, but how would I go about doing this?
Here is some of the code;
-(IBAction)removeAds:(id)sender
{
if (![MKStoreManager isFeaturePurchased:#"com.davidsapps.puzzler.removeads"]) { //
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Upgrade App" message:#"To upgrade and remove all advertisements from this app Please click OK to purchase the upgrade!" delegate:self cancelButtonTitle:#"No Thanks" otherButtonTitles:#"Yes Please",nil];
[alert show];
[alert release];
}
}
The alert it links to;
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0){
//cancel button clicked. Do something here or nothing here
}
else{
//other button indexes clicked
[[MKStoreManager sharedManager] buyFeature:#- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0){
//cancel button clicked. Do something here or nothing here
}
else{
//other button indexes clicked
[[MKStoreManager sharedManager] buyFeature:#"com.idevver.mybatterypal.upgrade"];
}
}
}
Using MKStoreKit
Is there anything I can do to make it remove the advertisements without the user having to restart the app?
Thanks,
Chris
EDIT - the advertisements are Admob Mediation, using this code in the ViewDidLoad
- (void)viewDidLoad {
bannerView_ = [[GADBannerView alloc] initWithAdSize:kGADAdSizeSmartBannerPortrait];
bannerView_.adUnitID = MY_BANNER_UNIT_ID;
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;
CGFloat screenXPos = (screenWidth /2);
CGFloat screenYPos = screenHeight - 90;
[bannerView_ setCenter:CGPointMake(screenXPos, screenYPos)];
bannerView_.rootViewController = self;
bannerView_.adUnitID = MY_BANNER_UNIT_ID;
bannerView_.rootViewController = self;
[self.view addSubview:bannerView_];
This is the code that actually calls the advertisement banner, it is in an if/else statement later in the viewDidLoad
if (![MKStoreManager isFeaturePurchased:#"com.davidsapps.puzzler.removeads"]) { //
[bannerView_ loadRequest:[GADRequest request]];
}
So I guess somehow when the feature is purchased, I need to add to the MKStoreManager.m file something to say dismiss the bannerView_ code above?
Would that work?
EDIT 2 - Full .m file for the in-app code (with thanks to MugunthKumar for a wonderful kit)
//
// MKStoreManager.m
// MKStoreKit
//
// Created by Mugunth Kumar on 17-Nov-2010.
// Copyright 2010 Steinlogic. All rights reserved.
// File created using Singleton XCode Template by Mugunth Kumar (http://mugunthkumar.com
// Permission granted to do anything, commercial/non-commercial with this file apart from removing the line/URL above
// Read my blog post at http://mk.sg/1m on how to use this code
// As a side note on using this code, you might consider giving some credit to me by
// 1) linking my website from your app's website
// 2) or crediting me inside the app's credits page
// 3) or a tweet mentioning #mugunthkumar
// 4) A paypal donation to mugunth.kumar#gmail.com
//
// A note on redistribution
// While I'm ok with modifications to this source code,
// if you are re-publishing after editing, please retain the above copyright notices
#import "MKStoreManager.h"
#import "GADBannerView.h"
#import "AppDelegate.h"
#interface MKStoreManager (PrivateMethods)
- (void) requestProductData;
- (BOOL) canCurrentDeviceUseFeature: (NSString*) featureID;
- (BOOL) verifyReceipt:(NSData*) receiptData;
- (void) enableContentForThisSession: (NSString*) productIdentifier;
#end
#implementation MKStoreManager
#synthesize purchasableObjects = _purchasableObjects;
#synthesize storeObserver = _storeObserver;
static NSString *ownServer = nil;
static __weak id<MKStoreKitDelegate> _delegate;
static MKStoreManager* _sharedStoreManager;
- (void)dealloc {
[_purchasableObjects release];
[_storeObserver release];
[_sharedStoreManager release];
[super dealloc];
}
#pragma mark Delegates
+ (id)delegate {
return _delegate;
}
+ (void)setDelegate:(id)newDelegate {
_delegate = newDelegate;
}
#pragma mark Singleton Methods
+ (MKStoreManager*)sharedManager
{
#synchronized(self) {
if (_sharedStoreManager == nil) {
#if TARGET_IPHONE_SIMULATOR
NSLog(#"You are running in Simulator MKStoreKit runs only on devices");
#else
_sharedStoreManager = [[self alloc] init];
_sharedStoreManager.purchasableObjects = [[NSMutableArray alloc] init];
[_sharedStoreManager requestProductData];
_sharedStoreManager.storeObserver = [[MKStoreObserver alloc] init];
[[SKPaymentQueue defaultQueue] addTransactionObserver:_sharedStoreManager.storeObserver];
#endif
}
}
return _sharedStoreManager;
}
+ (id)allocWithZone:(NSZone *)zone
{
#synchronized(self) {
if (_sharedStoreManager == nil) {
_sharedStoreManager = [super allocWithZone:zone];
return _sharedStoreManager; // assignment and return on first allocation
}
}
return nil; //on subsequent allocation attempts return nil
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
- (id)retain
{
return self;
}
- (unsigned)retainCount
{
return UINT_MAX; //denotes an object that cannot be released
}
- (void)release
{
//do nothing
}
- (id)autorelease
{
return self;
}
#pragma mark Internal MKStoreKit functions
- (void) restorePreviousTransactions
{
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
-(void) requestProductData
{
SKProductsRequest *request= [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObjects:
kFeatureAId,
kConsumableFeatureBId,
kConsumableBaseFeatureId,
nil]];
request.delegate = self;
[request start];
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
[self.purchasableObjects addObjectsFromArray:response.products];
#ifndef NDEBUG
for(int i=0;i<[self.purchasableObjects count];i++)
{
SKProduct *product = [self.purchasableObjects objectAtIndex:i];
NSLog(#"Feature: %#, Cost: %f, ID: %#",[product localizedTitle],
[[product price] doubleValue], [product productIdentifier]);
}
for(NSString *invalidProduct in response.invalidProductIdentifiers)
NSLog(#"Problem in iTunes connect configuration for product: %#", invalidProduct);
#endif
[request autorelease];
isProductsAvailable = YES;
if([_delegate respondsToSelector:#selector(productFetchComplete)])
[_delegate productFetchComplete];
}
// call this function to check if the user has already purchased your feature
+ (BOOL) isFeaturePurchased:(NSString*) featureId
{
return [[NSUserDefaults standardUserDefaults] boolForKey:featureId];
}
// Call this function to populate your UI
// this function automatically formats the currency based on the user's locale
- (NSMutableArray*) purchasableObjectsDescription
{
NSMutableArray *productDescriptions = [[NSMutableArray alloc] initWithCapacity:[self.purchasableObjects count]];
for(int i=0;i<[self.purchasableObjects count];i++)
{
SKProduct *product = [self.purchasableObjects objectAtIndex:i];
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[numberFormatter setLocale:product.priceLocale];
NSString *formattedString = [numberFormatter stringFromNumber:product.price];
[numberFormatter release];
// you might probably need to change this line to suit your UI needs
NSString *description = [NSString stringWithFormat:#"%# (%#)",[product localizedTitle], formattedString];
#ifndef NDEBUG
NSLog(#"Product %d - %#", i, description);
#endif
[productDescriptions addObject: description];
}
[productDescriptions autorelease];
return productDescriptions;
}
- (void) buyFeature:(NSString*) featureId
{
if([self canCurrentDeviceUseFeature: featureId])
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Review request approved", #"")
message:NSLocalizedString(#"You can use this feature for reviewing the app.", #"")
delegate:self
cancelButtonTitle:NSLocalizedString(#"Dismiss", #"")
otherButtonTitles:nil];
[alert show];
[alert release];
[self enableContentForThisSession:featureId];
return;
}
if ([SKPaymentQueue canMakePayments])
{
SKPayment *payment = [SKPayment paymentWithProductIdentifier:featureId];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"In-App Purchasing disabled", #"")
message:NSLocalizedString(#"Check your parental control settings and try again later", #"")
delegate:self
cancelButtonTitle:NSLocalizedString(#"Dismiss", #"")
otherButtonTitles: nil];
[alert show];
[alert release];
}
}
- (BOOL) canConsumeProduct:(NSString*) productIdentifier
{
int count = [[NSUserDefaults standardUserDefaults] integerForKey:productIdentifier];
return (count > 0);
}
- (BOOL) canConsumeProduct:(NSString*) productIdentifier quantity:(int) quantity
{
int count = [[NSUserDefaults standardUserDefaults] integerForKey:productIdentifier];
return (count >= quantity);
}
- (BOOL) consumeProduct:(NSString*) productIdentifier quantity:(int) quantity
{
int count = [[NSUserDefaults standardUserDefaults] integerForKey:productIdentifier];
if(count < quantity)
{
return NO;
}
else
{
count -= quantity;
[[NSUserDefaults standardUserDefaults] setInteger:count forKey:productIdentifier];
return YES;
}
}
-(void) enableContentForThisSession: (NSString*) productIdentifier
{
if([_delegate respondsToSelector:#selector(productPurchased:)])
[_delegate productPurchased:productIdentifier];
}
#pragma mark In-App purchases callbacks
// In most cases you don't have to touch these methods
-(void) provideContent: (NSString*) productIdentifier
forReceipt:(NSData*) receiptData
{
if(ownServer != nil && SERVER_PRODUCT_MODEL)
{
// ping server and get response before serializing the product
// this is a blocking call to post receipt data to your server
// it should normally take a couple of seconds on a good 3G connection
if(![self verifyReceipt:receiptData]) return;
}
NSRange range = [productIdentifier rangeOfString:kConsumableBaseFeatureId];
NSString *countText = [productIdentifier substringFromIndex:range.location+[kConsumableBaseFeatureId length]];
int quantityPurchased = [countText intValue];
if(quantityPurchased != 0)
{
int oldCount = [[NSUserDefaults standardUserDefaults] integerForKey:productIdentifier];
oldCount += quantityPurchased;
[[NSUserDefaults standardUserDefaults] setInteger:oldCount forKey:productIdentifier];
}
else
{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:productIdentifier];
}
[[NSUserDefaults standardUserDefaults] synchronize];
if([_delegate respondsToSelector:#selector(productPurchased:)])
[_delegate productPurchased:productIdentifier];
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"In-App Upgrade" message:#"Successfull removal of advertisements upgrade - thankyou" delegate:self cancelButtonTitle:#"ok" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
- (void) transactionCanceled: (SKPaymentTransaction *)transaction
{
#ifndef NDEBUG
NSLog(#"User cancelled transaction: %#", [transaction description]);
#endif
if([_delegate respondsToSelector:#selector(transactionCanceled)])
[_delegate transactionCanceled];
}
- (void) failedTransaction: (SKPaymentTransaction *)transaction
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[transaction.error localizedFailureReason]
message:[transaction.error localizedRecoverySuggestion]
delegate:self
cancelButtonTitle:NSLocalizedString(#"Dismiss", #"")
otherButtonTitles: nil];
[alert show];
[alert release];
}
#pragma mark In-App purchases promo codes support
// This function is only used if you want to enable in-app purchases for free for reviewers
// Read my blog post http://mk.sg/31
- (BOOL) canCurrentDeviceUseFeature: (NSString*) featureID
{
NSString *uniqueID = [[UIDevice currentDevice] uniqueIdentifier];
// check udid and featureid with developer's server
if(ownServer == nil) return NO; // sanity check
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#/%#", ownServer, #"featureCheck.php"]];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:60];
[theRequest setHTTPMethod:#"POST"];
[theRequest setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
NSString *postData = [NSString stringWithFormat:#"productid=%#&udid=%#", featureID, uniqueID];
NSString *length = [NSString stringWithFormat:#"%d", [postData length]];
[theRequest setValue:length forHTTPHeaderField:#"Content-Length"];
[theRequest setHTTPBody:[postData dataUsingEncoding:NSASCIIStringEncoding]];
NSHTTPURLResponse* urlResponse = nil;
NSError *error = [[[NSError alloc] init] autorelease];
NSData *responseData = [NSURLConnection sendSynchronousRequest:theRequest
returningResponse:&urlResponse
error:&error];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSASCIIStringEncoding];
BOOL retVal = NO;
if([responseString isEqualToString:#"YES"])
{
retVal = YES;
}
[responseString release];
return retVal;
}
// This function is only used if you want to enable in-app purchases for free for reviewers
// Read my blog post http://mk.sg/
-(BOOL) verifyReceipt:(NSData*) receiptData
{
if(ownServer == nil) return NO; // sanity check
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#/%#", ownServer, #"verifyProduct.php"]];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:60];
[theRequest setHTTPMethod:#"POST"];
[theRequest setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
NSString *receiptDataString = [[NSString alloc] initWithData:receiptData encoding:NSASCIIStringEncoding];
NSString *postData = [NSString stringWithFormat:#"receiptdata=%#", receiptDataString];
[receiptDataString release];
NSString *length = [NSString stringWithFormat:#"%d", [postData length]];
[theRequest setValue:length forHTTPHeaderField:#"Content-Length"];
[theRequest setHTTPBody:[postData dataUsingEncoding:NSASCIIStringEncoding]];
NSHTTPURLResponse* urlResponse = nil;
NSError *error = [[[NSError alloc] init] autorelease];
NSData *responseData = [NSURLConnection sendSynchronousRequest:theRequest
returningResponse:&urlResponse
error:&error];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSASCIIStringEncoding];
BOOL retVal = NO;
if([responseString isEqualToString:#"YES"])
{
retVal = YES;
}
[responseString release];
return retVal;
}
#end
When the purchase completes, it is up to you to remove the ads. Do something similar to this.
[bannerView removeFromSuperview];
All you have to do is hide the ads when the purchase completes.

problem submitting tweet to twitter from iphone

MGTwitterEngine.m
- (NSString *)username
{
return [[_username retain] autorelease];
}
- (NSString *)password
{
return [[_password retain] autorelease];
}
- (void)setUsername:(NSString *)newUsername password:(NSString *)newPassword
{
// Set new credentials.
[_username release];
_username = [newUsername retain];
[_password release];
_password = [newPassword retain];
if ([self clearsCookies]) {
// Remove all cookies for twitter, to ensure next connection uses new credentials.
NSString *urlString = [NSString stringWithFormat:#"%#://%#",
(_secureConnection) ? #"https" : #"http",
_APIDomain];
NSURL *url = [NSURL URLWithString:urlString];
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSEnumerator *enumerator = [[cookieStorage cookiesForURL:url] objectEnumerator];
NSHTTPCookie *cookie = nil;
while (cookie == [enumerator nextObject]) {
[cookieStorage deleteCookie:cookie];
}
}
}
- (NSString *)sendUpdate:(NSString *)status
{
return [self sendUpdate:status inReplyTo:0];
}
- (NSString *)sendUpdate:(NSString *)status inReplyTo:(unsigned long)updateID
{
if (!status) {
return nil;
}
NSString *path = [NSString stringWithFormat:#"statuses/update.%#", API_FORMAT];
NSString *trimmedText = status;
if ([trimmedText length] > MAX_MESSAGE_LENGTH) {
trimmedText = [trimmedText substringToIndex:MAX_MESSAGE_LENGTH];
}
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:0];
[params setObject:trimmedText forKey:#"status"];
if (updateID > 0) {
[params setObject:[NSString stringWithFormat:#"%u", updateID] forKey:#"in_reply_to_status_id"];
}
NSString *body = [self _queryStringWithBase:nil parameters:params prefixed:NO];
return [self _sendRequestWithMethod:HTTP_POST_METHOD path:path
queryParameters:params body:body
requestType:MGTwitterUpdateSendRequest
responseType:MGTwitterStatus];
}
TwitterPostViewController.m
- (IBAction)submitTweet{
[tweet resignFirstResponder];
if([[tweet text] length] > 0){
NSLog(#"%#",[[NSUserDefaults standardUserDefaults] valueForKey:#"TwitterUsername"]);
NSLog(#"%#",[[NSUserDefaults standardUserDefaults] valueForKey:#"TwitterPassword"]);
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
[engine sendUpdate:[tweet text]];
}
}
- (void)requestFailed:(NSString *)requestIdentifier withError:(NSError *)error{
NSLog(#"Fail: %#", error);
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
UIAlertView *failAlert;
if([error code] == 401){
failAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Incorrect Username & Password." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[failAlert setTag:10];
[failAlert setDelegate:self];
}
else
{
failAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Failed sending status to Twitter." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
}
[failAlert show];
[failAlert release];
}
It shows me the fail popup of Incorrect username and password
I have checked through nslog that username and password are going correct.
what could be wrong?
It looks like the version of MGTwitterEngine you're using is trying to use basic auth. That was switched off in Twitter in favour of OAuth. Get a newer version of MGTwitterEngine (or a fork that supports OAuth).

Getting Facebook Username in iPhone App

How can I get the username once anyone is logged in to facebook through my app ?
I am using :-
FBConnect API.
My Controller.m file-
#import "FacebookPOCViewController.h"
#implementation FacebookPOCViewController
#synthesize session = _session;
#synthesize logoutButton = _logoutButton;
#synthesize loginDialog = _loginDialog;
#synthesize facebookName = _facebookName;
- (void)viewDidLoad {
//PayTai Facebook App
static NSString* kApiKey = #"230600000000";
static NSString* kApiSecret = #"----------------------";
_session = [[FBSession sessionForApplication:kApiKey secret:kApiSecret delegate:self] retain];
// Load a previous session from disk if available. Note this will call session:didLogin if a valid session exists.
[_session resume];
[super viewDidLoad];
}
- (IBAction)loginTapped:(id)sender {
//_posting = YES;
// If we're not logged in, log in first...
if (![_session isConnected]) {
self.loginDialog = nil;
_loginDialog = [[FBLoginDialog alloc] init];
[_loginDialog show];
}
// If we have a session and a name, post to the wall!
else if (_facebookName != nil) {
//[self postToWall];
printf("Session");
}
// Otherwise, we don't have a name yet, just wait for that to come through.
}
- (IBAction)logoutButtonTapped:(id)sender {
[_session logout];
}
#pragma mark FBSessionDelegate methods
- (void)session:(FBSession*)session didLogin:(FBUID)uid {
[self getFacebookName];
}
- (void)session:(FBSession*)session willLogout:(FBUID)uid {
_logoutButton.hidden = YES;
_facebookName = nil;
}
pragma mark Get Facebook Name Helper
- (void)getFacebookName {
NSString* fql = [NSString stringWithFormat:#"select uid,name from user where uid == %lld", _session.uid];
//NSLog(#"%#",_session.uid);
NSDictionary* params = [NSDictionary dictionaryWithObject:fql forKey:#"query"];
[[FBRequest requestWithDelegate:self] call:#"facebook.fql.query" params:params];
}
#pragma mark FBRequestDelegate methods
- (void)request:(FBRequest*)request didLoad:(id)result {
if ([request.method isEqualToString:#"facebook.fql.query"]) {
NSArray* users = result;
NSDictionary* user = [users objectAtIndex:0];
NSString* name = [user objectForKey:#"name"];
self.facebookName = name;
_logoutButton.hidden = NO;
[_logoutButton setTitle:[NSString stringWithFormat:#"Logout as %#", name] forState:UIControlStateNormal];
//if (_posting) {
// [self postToWall];
// _posting = NO;
// }
}
}
Take a look at this. You can get almost any info of the user with the GRAPH api.
http://developers.facebook.com/docs/reference/api/user/
Example
/**
* Request the facebook name for the user
* Response will be obtained on delegate
*/
- (void) getFacebookName {
[facebook requestWithGraphPath:#"me?fields=id,name" andDelegate:self];
}
#pragma mark - FBRequestDelegate methods
- (void)request:(FBRequest *)request didLoad:(id)result {
NSLog(#"Result: %#", result);
NSDictionary *userInfo = (NSDictionary *)result;
userName = [userInfo objectForKey:#"name"];
fb_id = [userInfo objectForKey:#"id"];
}