Posting Score to FB using FBConnect - facebook

Hi all
Just wondering how I modify my code to post a score to Facebook
Currently all working with the following posting to facebook, just no score
#import "GameOverViewController.h"
#import "SoundEffects.h"
#import "FBConnect.h"
#implementation GameOverViewController
#synthesize scoreLabel, highScore;
#synthesize session = _session;
#synthesize postScoreButton = _postScoreButton;
#synthesize logoutButton = _logoutButton;
#synthesize loginDialog = _loginDialog;
#synthesize facebookName = _facebookName;
#synthesize posting = _posting;
- (void)viewDidLoad {
[super viewDidLoad];
NSString *gameOverPath = [[NSBundle mainBundle] pathForResource:#"gameover" ofType:#"png"];
UIImage *gameOver = [[UIImage alloc] initWithContentsOfFile: gameOverPath];
UIImageView *gameOverViewTemp = [[UIImageView alloc] initWithImage:gameOver];
[self.view addSubview:gameOverViewTemp];
gameOverText = [SpriteHelpers setupAnimatedSprite:self.view numFrames:3 withFilePrefix:#"gameovertext" withDuration:0.4 ofType:#"png" withValue:0];
gameOverText.center = CGPointMake(160, 90);
scoreLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 200, 320, 70)];
scoreLabel.text = [NSString stringWithFormat:#"%d points", highScore];
[self.view addSubview:scoreLabel];
scoreLabel.textColor = [UIColor whiteColor];
scoreLabel.backgroundColor = [UIColor clearColor];
scoreLabel.font = [UIFont boldSystemFontOfSize:42];
scoreLabel.textAlignment = UITextAlignmentCenter;
[gameOverViewTemp release];
[gameOver release];
// Set these values from your application page on http://www.facebook.com/developers
// Keep in mind that this method is not as secure as using the sessionForApplication:getSessionProxy:delegate method!
// These values are from a dummy facebook app I made called MyGrades - feel free to play around!
static NSString* kApiKey = #"2af22b07c9730d3d502a7a401b9e48d7";
static NSString* kApiSecret = #"738116a372130f659a761078de08b3d4";
_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];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view removeFromSuperview];
[self release];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
}
- (IBAction)postScoreTapped:(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];
}
// 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];
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:#"Facebook: Logout as %#", name] forState:UIControlStateNormal];
if (_posting) {
[self postToWall];
_posting = NO;
}
}
}
#pragma mark Post to Wall Helper
- (void)postToWall {
FBStreamDialog* dialog = [[[FBStreamDialog alloc] init] autorelease];
dialog.userMessagePrompt = #"Enter your message:";
dialog.attachment = [NSString stringWithFormat:#"{\"name\":\"%# just played SpaceRide on the iPhone!\",\"href\":\"http://www.spaceride.me/\",\"caption\":\"%# must be really skillful!\",\"description\":\"\",\"media\":[{\"type\":\"image\",\"src\":\"http://www.spaceride.me/fbicon.png\",\"href\":\"http://www.spaceride.me/\"}]}",
_facebookName, _facebookName];
dialog.actionLinks = #"[{\"text\":\"Get SpaceRide!\",\"href\":\"http://www.spaceride.me/\"}]";
[dialog show];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[scoreLabel release];
[super dealloc];
}
#end

Change:
dialog.attachment = [NSString stringWithFormat:#"{\"name\":\"%# just played SpaceRide on the iPhone!\",\"href\":\"http://www.spaceride.me/\",\"caption\":\"%# must be really skillful!\",\"description\":\"\",\"media\":[{\"type\":\"image\",\"src\":\"http://www.spaceride.me/fbicon.png\",\"href\":\"http://www.spaceride.me/\"}]}",
_facebookName, _facebookName];
To something like:
dialog.attachment = [NSString stringWithFormat:#"{\"name\":\"%# just got %d playing SpaceRide on the iPhone!\",\"href\":\"http://www.spaceride.me/\",\"caption\":\"%# must be really skillful!\",\"description\":\"\",\"media\":[{\"type\":\"image\",\"src\":\"http://www.spaceride.me/fbicon.png\",\"href\":\"http://www.spaceride.me/\"}]}",
_facebookName, score, _facebookName];
Change 'score' to the name of your integer score variable.

Related

Get file name and Data Type from ELCAlbumPickerController

I am working on ELCAlbumPickerController, i am able to select multiple images and upload, but in addition i want to get the file name and datatype of the file. how can i do that?
I am able to select either image or video , how can i select both image and video and any file at a time?
Please find my code below for your reference.
- (void)viewDidLoad {
UIImage *anImage = [UIImage imageNamed:#"elc-ios-icon.png"];
NSArray *Items = [NSArray arrayWithObjects:
#"A text line",
anImage, nil];
UIActivityViewController *ActivityView =
[[UIActivityViewController alloc]
initWithActivityItems:Items applicationActivities:nil];
[self presentViewController:ActivityView animated:YES completion:nil];
}
- (IBAction)launchController
{
ELCAlbumPickerController *albumController = [[ELCAlbumPickerController alloc] initWithNibName: nil bundle: nil];
ELCImagePickerController *elcPicker = [[ELCImagePickerController alloc] initWithRootViewController:albumController];
[albumController setParent:elcPicker];
[elcPicker setDelegate:self];
ELCImagePickerDemoAppDelegate *app = (ELCImagePickerDemoAppDelegate *)[[UIApplication sharedApplication] delegate];
if ([app.viewController respondsToSelector:#selector(presentViewController:animated:completion:)]){
[app.viewController presentViewController:elcPicker animated:YES completion:nil];
} else {
[app.viewController presentModalViewController:elcPicker animated:YES];
}
[elcPicker release];
[albumController release];
}
- (IBAction)launchSpecialController
{
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
self.specialLibrary = library;
[library release];
NSMutableArray *groups = [NSMutableArray array];
[_specialLibrary enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if (group) {
[groups addObject:group];
} else {
// this is the end
[self displayPickerForGroup:[groups objectAtIndex:0]];
}
} failureBlock:^(NSError *error) {
self.chosenImages = nil;
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:#"Error" message:[NSString stringWithFormat:#"Album Error: %# - %#", [error localizedDescription], [error localizedRecoverySuggestion]] delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
[alert release];
NSLog(#"A problem occured %#", [error description]);
// an error here means that the asset groups were inaccessable.`
// Maybe the user or system preferences refused access.
}];
}
- (void)displayPickerForGroup:(ALAssetsGroup *)group
{
ELCAssetTablePicker *tablePicker = [[ELCAssetTablePicker alloc] initWithNibName: nil bundle: nil];
tablePicker.singleSelection = YES;
tablePicker.immediateReturn = YES;
ELCImagePickerController *elcPicker = [[ELCImagePickerController alloc] initWithRootViewController:tablePicker];
elcPicker.delegate = self;
tablePicker.parent = elcPicker;
// Move me
tablePicker.assetGroup = group;
[tablePicker.assetGroup setAssetsFilter:[ALAssetsFilter allAssets]];
if ([self respondsToSelector:#selector(presentViewController:animated:completion:)]){
[self presentViewController:elcPicker animated:YES completion:nil];
} else {
[self presentModalViewController:elcPicker animated:YES];
}
[tablePicker release];
[elcPicker release];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
return YES;
} else {
return toInterfaceOrientation != UIInterfaceOrientationPortraitUpsideDown;
}
}
#pragma mark ELCImagePickerControllerDelegate Methods
- (void)elcImagePickerController:(ELCImagePickerController *)picker didFinishPickingMediaWithInfo:(NSArray *)info
{
if ([self respondsToSelector:#selector(dismissViewControllerAnimated:completion:)]){
[self dismissViewControllerAnimated:YES completion:nil];
} else {
[self dismissModalViewControllerAnimated:YES];
}
for (UIView *v in [_scrollView subviews]) {
[v removeFromSuperview];
}
CGRect workingFrame = _scrollView.frame;
workingFrame.origin.x = 0;
images = [NSMutableArray arrayWithCapacity:[info count]];
for(NSDictionary *dict in info) {
UIImage *image = [dict objectForKey:UIImagePickerControllerOriginalImage];
[images addObject:image];
UIImageView *imageview = [[UIImageView alloc] initWithImage:image];
[imageview setContentMode:UIViewContentModeScaleAspectFit];
imageview.frame = workingFrame;
[_scrollView addSubview:imageview];
[imageview release];
workingFrame.origin.x = workingFrame.origin.x + workingFrame.size.width;
}
self.chosenImages = images;
NSLog(#"Images:%#",images);
[_scrollView setPagingEnabled:YES];
[_scrollView setContentSize:CGSizeMake(workingFrame.origin.x, workingFrame.size.height)];
for (int i=0; i< images.count; i++) {
NSData *image = UIImageJPEGRepresentation(images[i], 0.1);
NSLog(#"NSDATA:%#",image);
NSMutableString *urlString = [[NSMutableString alloc] initWithFormat:#"name=thefile&&filename=recording"];
[urlString appendFormat:#"%#", image];
NSLog(#"urlstring:%#",urlString);
NSData *postData = [urlString dataUsingEncoding:NSASCIIStringEncoding
allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSString * namecount=[NSString stringWithFormat:#"fn%i.png",i];
NSString * baseurl =[[NSString alloc]initWithFormat:#"http://199.198.12.555/serviceService.svc/serviceupload?fileName=%#",namecount];
NSURL *url = [NSURL URLWithString:baseurl];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
[urlRequest setHTTPMethod: #"POST"];
[urlRequest setValue:postLength forHTTPHeaderField:#"Content-Length"];
[urlRequest setValue:#"application/x-www-form-urlencoded"
forHTTPHeaderField:#"Content-Type"];
[urlRequest setHTTPBody:image];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:urlRequest delegate:self];
[connection start];
}
NSLog(#"%#",images[0]);
NSLog(#"%lu",(unsigned long)images.count);
}
-(IBAction)upload:(id)sender{
}
- (void)elcImagePickerControllerDidCancel:(ELCImagePickerController *)picker
{
if ([self respondsToSelector:#selector(dismissViewControllerAnimated:completion:)]){
[self dismissViewControllerAnimated:YES completion:nil];
} else {
[self dismissModalViewControllerAnimated:YES];
}
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload
{
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc
{
[_specialLibrary release];
[_scrollView release];
[super dealloc];
}
#end
#implementation APActivityProvider
- (id) activityViewController:(UIActivityViewController *)activityViewController
itemForActivityType:(NSString *)activityType
{
if ( [activityType isEqualToString:UIActivityTypePostToTwitter] )
return #"This is a #twitter post!";
if ( [activityType isEqualToString:UIActivityTypePostToFacebook] )
return #"This is a facebook post!";
if ( [activityType isEqualToString:UIActivityTypeMessage] )
return #"SMS message text";
if ( [activityType isEqualToString:UIActivityTypeMail] )
return #"Email text here!";
if ( [activityType isEqualToString:#"it.albertopasca.myApp"] )
return #"OpenMyapp custom text";
return nil;
}
- (id) activityViewControllerPlaceholderItem:(UIActivityViewController *)activityViewController { return #""; }
#end
#implementation APActivityIcon
- (NSString *)activityType { return #"it.albertopasca.myApp"; }
- (NSString *)activityTitle { return #"Open Maps"; }
- (UIImage *) activityImage { return [UIImage imageNamed:#"elc-ios-icon.png"]; }
- (BOOL) canPerformWithActivityItems:(NSArray *)activityItems { return YES; }
- (void) prepareWithActivityItems:(NSArray *)activityItems { }
- (UIViewController *) activityViewController { return nil; }
- (void) performActivity {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"maps://"]];
}
#end
Thanks
You can get the asset URL using the key UIImagePickerControllerReferenceURL which would give the 'name', but that probably won't be very useful as its probably a UUID. The UIImagePickerControllerMediaType key contains the type.

iOS: foursquare request fails

I am assigned to work with foursquare just recently. I have an app that needs to be authenticated and access the foursquare environment. I am having trouble with the following code to access checkins. I had already successfully made the authentication but the thing is that when I made a check in request, an errorType invalid_auth code 401 appears. I just don't know what's wrong with this.
Here is my full code; I am using fsq wrapper I found in github:
#import "FSQViewController.h"
#define kClientID #"XXXXXXXXXXXXXXXXXXXXXXX"
#define kCallbackURL #"invitation://foursquare"
#interface FSQViewController()
#property(nonatomic,readwrite,strong) BZFoursquare *foursquare;
#property(nonatomic,strong) BZFoursquareRequest *request;
#property(nonatomic,copy) NSDictionary *meta;
#property(nonatomic,copy) NSArray *notifications;
#property(nonatomic,copy) NSDictionary *response;
#end
#implementation FSQViewController
#synthesize foursquare = foursquare_;
#synthesize request = request_;
#synthesize meta = meta_;
#synthesize notifications = notifications_;
#synthesize response = response_;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (id) initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if(self){
self.foursquare = [[BZFoursquare alloc]initWithClientID:kClientID callbackURL:kCallbackURL];
foursquare_.version = #"20120206";
foursquare_.locale = [[NSLocale currentLocale]objectForKey:NSLocaleLanguageCode];
foursquare_.sessionDelegate = (id<BZFoursquareSessionDelegate>) self;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#pragma mark -
#pragma mark BZFoursquareRequestDelegate
- (void)requestDidFinishLoading:(BZFoursquareRequest *)request {
NSLog(#"test");
self.meta = request.meta;
self.notifications = request.notifications;
self.response = request.response;
self.request = nil;
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
- (void)request:(BZFoursquareRequest *)request didFailWithError:(NSError *)error {
NSLog(#"HERE > %s: %#", __PRETTY_FUNCTION__, error);
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:[[error userInfo] objectForKey:#"errorDetail"] delegate:nil cancelButtonTitle:NSLocalizedString(#"OK", #"") otherButtonTitles:nil];
[alertView show];
self.meta = request.meta;
self.notifications = request.notifications;
self.response = request.response;
self.request = nil;
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
#pragma mark -
#pragma mark BZFoursquareSessionDelegate
- (void)foursquareDidAuthorize:(BZFoursquare *)foursquare {
NSLog(#"authorized!");
}
- (void)foursquareDidNotAuthorize:(BZFoursquare *)foursquare error:(NSDictionary *)errorInfo {
NSLog(#"not authorized! %s: %#", __PRETTY_FUNCTION__, errorInfo);
}
- (IBAction)click:(id)sender {
if (![foursquare_ isSessionValid]){
NSLog(#"here");
[foursquare_ startAuthorization];
} else {
[foursquare_ invalidateSession];
}
}
- (IBAction)checkin:(id)sender {
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:#"4d341a00306160fcf0fc6a88", #"venueId", #"public", #"broadcast", kClientID, #"oauth_token", nil];
self.request = [foursquare_ requestWithPath:#"checkins/add" HTTPMethod:#"POST" parameters:parameters delegate:self];
[request_ start];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
}
#end
can you help me guys? any help will highly be appreciated.
https://developer.foursquare.com/overview/responses
401 (Unauthorized) The OAuth token was provided but was invalid.
Might you have somehow corrupted your oauth token?
I am using the code below & it is working for me :
NSDictionary *parameters = #{#"venueId": #"4a0c6465f964a5202a751fe3", #"broadcast": #"public",#"oauth_token":kClientID};

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"];
}

how can i integrate ticker in iphone application

i want to run my view based window application with ticker.i have code for ticker but it is in cocoa..
so how can i integrate cocoa application in my project.?
this is TickerView.h file
#import <Cocoa/Cocoa.h>
#interface TickerView : NSTextView {
#private
NSTimer *mTimer;
double mOffset;
}
- (NSString *)stringValue;
- (void)setStringValue:(NSString *)stringValue;
- (void)appendString:(NSString *)s;
- (IBAction)startAnimation:(id)sender;
- (IBAction)stopAnimation:(id)sender;
#end
This is TickerView.m file
#import "TickerView.h"
#implementation TickerView
- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setEditable:NO];
NSTextContainer *container = [self textContainer];
[container setWidthTracksTextView:NO];
[container setContainerSize:NSMakeSize(99999., frame.size.height)];
}
return self;
}
- (void)dealloc {
[self stopAnimation:self];
[super dealloc];
}
- (void)drawRect:(NSRect)rect {
[super drawRect:rect];
}
- (NSString *)stringValue {
return [[self textStorage] string];
}
- (NSDictionary *)standardAttributes {
return [NSDictionary dictionaryWithObjectsAndKeys:
[NSFont fontWithName:#"Helvetica" size:([self frame].size.height * 0.8)], NSFontAttributeName,
[NSColor redColor], NSForegroundColorAttributeName,
nil];
}
- (void)setStringValue:(NSString *)s {
NSRange fullRange = NSMakeRange(0, [[self textStorage] length]);
NSAttributedString *sa = [[[NSAttributedString alloc]initWithString:s attributes:[self standardAttributes]] autorelease];
[[self textStorage] replaceCharactersInRange:fullRange withAttributedString:sa];
}
- (void)appendString:(NSString *)s {
NSRange endRange = NSMakeRange([[self textStorage] length], 0);
NSAttributedString *sa = [[[NSAttributedString alloc]initWithString:s attributes:[self standardAttributes]] autorelease];
[[self textStorage] replaceCharactersInRange:endRange withAttributedString:sa];
}
- (IBAction)startAnimation:(id)sender {
if (nil == mTimer) {
mTimer = [NSTimer scheduledTimerWithTimeInterval:1./60. target:self selector:#selector(step:) userInfo:nil repeats:YES];
}
}
- (IBAction)stopAnimation:(id)sender {
if (mTimer) {
[mTimer invalidate];
[mTimer release];
mTimer = nil;
}
}
- (void)step:(NSTimer *)timer {
mOffset -= 2; // pixels per tick
[self setTextContainerInset:NSMakeSize(mOffset, 0)];
[self setNeedsDisplay:YES];
}
#end
You can't just drop it in (as far as I know).
I'd do it by changing your inheritance from NSTextView to UILabel and reading the docs for that. then just work through the code bit by bit until it works ;)

iphoneSDK: UINavigationController Back button is causing app to crash

My app is crashing when I move between ViewControllers. This is the sequence that causes the crash salesViewController displays confirmViewController. When I press the back button in confirmViewController to go back to salesViewController, the application crashes.
I am not sure why. Here is the code for both of the controllers.
Thanks in advance.
#import "salesViewController.h"
#implementation salesViewController
#synthesize txtCardNumber;
#synthesize txtExpires;
#synthesize txtGrandTotal;
#synthesize txtZip;
#synthesize txtEmail;
#synthesize txtCCV2;
#synthesize txtInvoice;
//#synthesize button;
#synthesize strSaleType;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if(self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
}
return self;
}
-(IBAction)btnTipCalculator:(id)sender
{
NSLog(#"I was pressed");
tipCalcViewController *tipVC = [[tipCalcViewController alloc] initWithNibName:#"tipCalcView" bundle:nil];
tipVC.delegate = self;
tipVC.passedTotal = txtGrandTotal.text;
[self presentModalViewController:tipVC animated:YES];
[tipVC release];
}
-(IBAction)btnDateSelector:(id)sender
{
NSLog(#"I was pressed");
DatePickerViewController *datePickerViewController = [[DatePickerViewController alloc] initWithNibName:#"datePickerView" bundle:nil];
datePickerViewController.delegate = self;
[self presentModalViewController:datePickerViewController animated:YES];
[datePickerViewController release];
}
-(void)datePickerViewController:(DatePickerViewController *)controller didChooseDate:(NSString *)chosenDate{
NSLog(#"Chosen Date as String: %#", chosenDate );
txtExpires.text = chosenDate;
//do processing here... for example let's set the text of the button to the chosen date
//[button setTitle: chosenDate forState: UIControlStateNormal];
[self dismissModalViewControllerAnimated:YES];
}
//callback for modal tipCalculator
-(void)tipCalcViewController:(tipCalcViewController *)controller didChooseTip:(NSString *)chosenTip
{
NSString *strNewTotal = chosenTip;
//close tip calculator
[self dismissModalViewControllerAnimated:YES];
//update GUI
txtGrandTotal.text = strNewTotal;
}
-(void)btnSubmitClicked
{
NSURL *url = [NSURL URLWithString:#"https://www.eProcessingNetwork.Com/cgi-bin/tdbe/transact.pl"];
//NSURL *url = [NSURL URLWithString:#"https://www.eprocessingnetwork.com/Reflect/Post.pl"];
ASIFormDataRequest *request = [[[ASIFormDataRequest alloc]
initWithURL:url] autorelease];
//get settings
//NSUserDefaults *options = [NSUserDefaults standardUserDefaults];
//NSString *acctNumber = [options stringForKey:#"accountNumber"];
//NSString *restrictKey = [options stringForKey:#"restrictKey"];
//uncomment for actual
//[request setPostValue:acctNumber forKey:#"ePNAccount"];
//[request setPostValue:restrictKey forKey:#"RestrictKey"];
if([strSaleType compare:#"Test"] == NSOrderedSame)
{
//FOR TESTING ONLY: UNCOMMENT ABOVE FOR ACTUAL ACCOUNT
[request setPostValue:#"080880" forKey:#"ePNAccount"];
[request setPostValue:#"yFqqXJh9Pqnugfr" forKey:#"RestrictKey"];
}
//FOR TESTING ONLY: UNCOMMENT ABOVE FOR ACTUAL ACCOUNT
[request setPostValue:#"080880" forKey:#"ePNAccount"];
[request setPostValue:#"yFqqXJh9Pqnugfr" forKey:#"RestrictKey"];
//transaction type
if([strSaleType compare:#"Sale"] == NSOrderedSame)
{
[request setPostValue:#"Sale" forKey:#"TranType"];
}
if([strSaleType compare:#"Refund"] == NSOrderedSame)
{
[request setPostValue:#"Return" forKey:#"TranType"];
}
if([strSaleType compare:#"Test"] == NSOrderedSame)
{
[request setPostValue:#"Sale" forKey:#"TranType"];
}
//request no HTML output
[request setPostValue:#"No" forKey:#"HTML"];
//needed to get transID for signature capture
[request setPostValue:#"report" forKey:#"Inv"];
//card number
[request setPostValue:txtCardNumber.text forKey:#"CardNo"];
//parse date
NSString *strDateFull = txtExpires.text;
NSString *strMonth = [strDateFull substringWithRange: NSMakeRange(0, 2)];
NSString *strYear = [strDateFull substringWithRange: NSMakeRange(3, 2)];
//expire month
[request setPostValue:strMonth forKey:#"ExpMonth"];
//expire year
[request setPostValue:strYear forKey:#"ExpYear"];
//total, send as you would write it. no dollar sign needed
[request setPostValue:txtGrandTotal.text forKey:#"Total"];
//address - this makes TBDE ignore requests with no address
[request setPostValue:#"1" forKey:#"SKIP_MISSING"];
//zip
[request setPostValue:txtZip.text forKey:#"Zip"];
//ccv2
[request setPostValue:#"CVV2Type" forKey:#"1"];
[request setPostValue:txtCCV2.text forKey:#"123"];
//email
[request setPostValue:txtEmail.text forKey:#"EMail"];
//invoice # - optional
[request setPostValue:txtInvoice.text forKey:#"Invoice"];
//blocking of course
[request start];
// get confirmation
confirmViewController *anotherViewController = [[confirmViewController alloc] initWithNibName:#"confirmView" bundle:nil];
//set properties
anotherViewController.strConfirmation = [request responseString];
anotherViewController.strCardNumber = txtCardNumber.text;
anotherViewController.strExpires = txtExpires.text;
anotherViewController.strAmount = txtGrandTotal.text;
[self.navigationController pushViewController:anotherViewController animated:YES];
//reset interface
if([anotherViewController.strApproval compare:#"""Y"] == NSOrderedSame)
{
txtCardNumber.text = #"";
txtExpires.text = #"";
txtGrandTotal.text = #"";
txtZip.text = #"";
txtCCV2.text = #"";
txtEmail.text = #"";
txtInvoice.text = #"";
}
[anotherViewController release];
/*
//display the results
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Info"
message:[request responseString]
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alert show];
[alert release];
*/
}
/*
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
// Custom initialization
}
return self;
}
*/
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
//Needed to get events
[txtCardNumber setDelegate:self];
[txtExpires setDelegate:self];
[txtGrandTotal setDelegate:self];
[txtZip setDelegate:self];
[txtEmail setDelegate:self];
[txtCCV2 setDelegate:self];
[txtInvoice setDelegate:self];
//adjust title depending on sale type
if([strSaleType compare:#"Sale"] == NSOrderedSame)
{
self.title = #"Sales";
NSLog(#"Passed in sale type: %#", strSaleType );
}
if([strSaleType compare:#"Refund"] == NSOrderedSame)
{
self.title = #"Refunds";
NSLog(#"Passed here in sale type: %#", strSaleType );
}
if([strSaleType compare:#"Test"] == NSOrderedSame)
{
self.title = #"Testing";
NSLog(#"Passed in sale type: %#", strSaleType );
}
//add additional button
UIBarButtonItem *submitButton = [[UIBarButtonItem alloc] initWithTitle:#"Submit" style:UIBarButtonItemStylePlain target:self action:#selector(btnSubmitClicked)];
self.navigationItem.rightBarButtonItem = submitButton;
[submitButton release];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
if(txtCardNumber != NULL)
{
[txtCardNumber release];
}
if(txtExpires != NULL)
{
[txtExpires release];
}
if(txtGrandTotal != NULL)
{
[txtGrandTotal release];
}
if(txtZip != NULL)
{
[txtZip release];
}
if(txtEmail != NULL)
{
[txtEmail release];
}
if(txtCCV2 != NULL)
{
[txtCCV2 release];
}
if(txtInvoice != NULL)
{
[txtInvoice release];
}
if(strSaleType != NULL)
{
[strSaleType release];
}
[super dealloc];
}
#end
#import "confirmViewController.h"
#implementation confirmViewController
#synthesize lblStatus;
#synthesize lblCardType;
#synthesize lblCardNumber;
#synthesize lblExpires;
#synthesize lblAmount;
#synthesize lblApproval;
#synthesize strConfirmation;
#synthesize strCardNumber;
#synthesize strExpires;
#synthesize strAmount;
#synthesize strApproval;
-(void)btnSignatureClicked
{
sigCaptureViewController *anotherViewController = [[sigCaptureViewController alloc] initWithNibName:#"sigCaptureView" bundle:nil];
[self.navigationController pushViewController:anotherViewController animated:YES];
[anotherViewController release];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
//prepare confirmation, all that is needed is the first string
NSArray *strings = [strConfirmation componentsSeparatedByString: #","];
NSString *strPreParsed = [strings objectAtIndex:0];
//break out yes/no so we can set status
//NSString *strYesNO = [strPreParsed substringToIndex:2];
NSString *strYesOrNo = [strPreParsed substringWithRange: NSMakeRange(1, 1)];
//save approval for later
strApproval = strYesOrNo;
//debug
NSLog(#"strNo= %#",strYesOrNo);
NSLog(#"strPreParsed= %#", strPreParsed);
//set results
if([strYesOrNo compare:#"Y"] == NSOrderedSame)
{
lblStatus.text = #"Approved";
lblStatus.textColor = [UIColor greenColor];
}
if([strYesOrNo compare:#"N"] == NSOrderedSame)
{
lblStatus.text = #"Declined";
lblStatus.textColor = [UIColor redColor];
}
if([strYesOrNo compare:#"U"] == NSOrderedSame)
{
lblStatus.text = #"Try Again";
lblStatus.textColor = [UIColor redColor];
}
//set card type
if([lblCardNumber.text compare:#"4"] == NSOrderedSame)
{
lblCardType.text = #"Visa";
}
if([lblCardNumber.text compare:#"5"] == NSOrderedSame)
{
lblCardType.text = #"Master";
}
if([lblCardNumber.text compare:#"6"] == NSOrderedSame)
{
lblCardType.text = #"Discover";
}
//set cardnumber
lblCardNumber.text = strCardNumber;
//set expires
lblExpires.text = strExpires;
//set amount
lblAmount.text = strAmount;
//set approval string
lblApproval.text = strPreParsed;
//add signature button
UIBarButtonItem *signatureButton = [[UIBarButtonItem alloc] initWithTitle:#"Signature" style:UIBarButtonItemStylePlain target:self action:#selector(btnSignatureClicked)];
self.navigationItem.rightBarButtonItem = signatureButton;
[signatureButton release];
//set title
self.title = #"Approval";
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
if(lblCardType != NULL)
{
[lblCardType release];
}
if(lblCardNumber != NULL)
{
[lblCardNumber release];
}
if(lblExpires != NULL)
{
[lblExpires release];
}
if(lblAmount != NULL)
{
[lblAmount release];
}
if(lblApproval != NULL)
{
[lblApproval release];
}
if(lblStatus != NULL)
{
[lblStatus release];
}
if(strConfirmation != NULL)
{
[strConfirmation release];
}
if(strCardNumber != NULL)
{
[strCardNumber release];
}
if(strExpires != NULL)
{
[strExpires release];
}
if(strAmount != NULL)
{
[strAmount release];
}
if(strApproval != NULL)
{
[strApproval release];
}
[super dealloc];
}
#end
I think you are releasing properties that should not be released, for instance you create strYesOrNo like this:
NSString *strYesOrNo = [strPreParsed substringWithRange: NSMakeRange(1, 1)];
without allocating the string. So the string belongs to the viewDidLoad function and will be released by this function. But after creating the strYesOrNo you assign it to a class property, like this:
strApproval = strYesOrNo;
By the time you dealloc your viewcontroller you try to release strApproval, but the viewDidLoad allready released this value and you get a bad-access. You can solve this problem by allocating the memory for strApproval like:
strApproval = [[NSString alloc] initWithString:strYesOrNo];
I did not go through all your code so maybe this is also true for some other properties. Hope this helped.