iphoneSDK: UINavigationController Back button is causing app to crash - iphone

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.

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.

Use Block Based Action Sheet

I am using this as a bit of a blueprint for setting up a block based action sheet. My actions for the action sheet are Cancel, Download, and Stream. I changed the BlockBasedActionSheet.h to:
#interface BlockBasedActionSheet : UIActionSheet<UIActionSheetDelegate> {
}
#property (copy) void (^cancelBlock)();
#property (copy) void (^downloadBlock)();
#property (copy) void (^streamBlock)();
- (id)initWithTitle:(NSString *)title cancelButtonTitle:(NSString *)cancelButtonTitle downloadButtonTitle:(NSString *)downloadButtonTitle streamButtonTitle:(NSString *)streamButtonTitle cancelAction:(void (^)())cancelBlock downloadAction:(void (^)())downloadBlock streamAction:(void (^)())streamBlock;
#end
and the BlockBasedActionSheet.m to:
#implementation BlockBasedActionSheet
#synthesize cancelBlock = _cancelBlock, streamBlock = _streamBlock, downloadBlock = _downloadBlock;
- (id)initWithTitle:(NSString *)title cancelButtonTitle:(NSString *)cancelButtonTitle downloadButtonTitle:(NSString *)downloadButtonTitle streamButtonTitle:(NSString *)streamButtonTitle cancelAction:(void (^)())cancelBlock downloadAction:(void (^)())downloadBlock streamAction:(void (^)())streamBlock
{
self = [super initWithTitle:title delegate:self cancelButtonTitle:cancelButtonTitle destructiveButtonTitle:nil otherButtonTitles:downloadButtonTitle, streamButtonTitle, nil];
if (self) {
_cancelBlock = Block_copy(cancelBlock);
_downloadBlock = Block_copy(downloadBlock);
_streamBlock = Block_copy(streamBlock);
}
return self;
}
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
NSAssert(actionSheet == self, #"Wrong Action Sheet passed");
if (buttonIndex == 0) {
if (self.cancelBlock) {
self.cancelBlock();
}
}
if (buttonIndex == 1) {
if (self.downloadBlock) {
self.downloadBlock();
}
}
if (buttonIndex == 2) {
if (self.streamBlock) {
self.streamBlock();
}
}
}
#end
In my TableView didSelectRowAtIndexPath, I put the following:
BlockBasedActionSheet *askSheet =
[[BlockBasedActionSheet alloc]
initWithTitle:#"What Do You Want To Do" cancelButtonTitle:#"Cancel" downloadButtonTitle:#"Download" streamButtonTitle:#"Stream" cancelAction:^ {
}downloadAction:^ {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
CGRect frame = CGRectMake(0, 49, 160, 50);
progress = [[UIProgressView alloc] initWithFrame:frame];
cell.contentView.tag = 100;
[cell.contentView addSubview:progress];
RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
NSURL *url = [NSURL URLWithString:entry.articleUrl];
self.nameit = entry.articleTitle;
NSURLRequest *theRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
receivedData = [[NSMutableData alloc] initWithLength:0];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:YES];
}streamAction:^ {
if (_webViewController == nil) {
self.webViewController = [[[WebViewController alloc] initWithNibName:#"WebViewController" bundle:[NSBundle mainBundle]] autorelease];
}
RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
_webViewController.entry = entry;
[self.navigationController pushViewController:_webViewController animated:YES];
}];
[askSheet showInView:self.tabBarController.view];
[askSheet release];
The Action Sheet Presents from top to bottom:
Download
Stream
Cancel
When I press Download, the Cancel action performs;
Stream, the Download action performs;
Cancel, the Stream Action performs
What have I done wrong that it is getting out of order?
try this:
if (buttonIndex == [self cancelButtonIndex]) {
if (self.cancelBlock) {
self.cancelBlock();
}
}
if (buttonIndex == [self firstOtherButtonIndex]) {
if (self.downloadBlock) {
self.downloadBlock();
}
}
if (buttonIndex == [self firstOtherButtonIndex] +1) {
if (self.streamBlock) {
self.streamBlock();
}
}

Code works fine on iOS5 but not on iOS4.3

I have code that works fine on iOS5 but does not work on iOS4.3, I'm trying to display a loading screen with a progress bar from a navigation controller that has a UIViewController as the root view.
The problem is that on iOS4.3 the loading screen doesn't appear at the right time, it appears just before the view of the second view controller is displayed and then disappears quickly.
Here's the code :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
NSUserDefaults * standardUserDefaults = [NSUserDefaults standardUserDefaults];
CGSize s = [[UIScreen mainScreen] bounds].size;
[standardUserDefaults setObject:#"" forKey:#"display_resolution"];
if((int)s.width == 640 && (int)s.height == 960)[standardUserDefaults setObject:#"#2x" forKey:#"display_resolution"];
[standardUserDefaults synchronize];
AC_Loading *loading = [[[AC_Loading alloc] initWithNibName:#"AC_Loading_iPhone" bundle:nil] autorelease];
_navController0 = [[[UINavigationController alloc]initWithRootViewController:loading]autorelease];
_navController0.navigationBar.hidden = YES;
self.window.rootViewController = self.navController0;
[self.window makeKeyAndVisible];
return YES;
}
-
Edit
I figured out that the problem came from AC_Loading's code, this UIViewController has to display a loading screen with a progress view that updates according to database stat (I'm creating a sqlite3 database and updating it if needed and showing progress).While using this code on iOS5 works but it doesn't on iOS4.x I thought is because of the loop inside viewDidAppear (While pr<1.0):
#import "AC_Loading.h"
#import "database.h"
#import "AC_Menu.h"
#implementation AC_Loading
#synthesize logo;
#synthesize progress;
#synthesize informations;
#synthesize CLController;
float pr = 0.14;
int p = 0;
AC_Menu *menu;
NSUserDefaults *standardUserDefaults;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (void)viewDidLoad
{
[super viewDidLoad];
standardUserDefaults = [NSUserDefaults standardUserDefaults];
[standardUserDefaults setObject:#"NO" forKey:#"geoloc"];
[standardUserDefaults synchronize];
NSLog(#"%#", [NSString stringWithFormat:#"intro%#%#", [standardUserDefaults stringForKey:#"display_resolution"], #".jpg"]);
[logo setImage:[UIImage imageNamed:[NSString stringWithFormat:#"intro%#%#", [standardUserDefaults stringForKey:#"display_resolution"], #".jpg"]]];
//[progress setProgressTintColor:[UIColor purpleColor]];
[progress setProgress:0.14];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[self setLogo:nil];
[self setInformations:nil];
[self setProgress:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:YES];
database *DB = [[database alloc] init];
[DB checkDB];
NSString *message = #"Chargement des données";
if([DB isCreated]== NO && [DB upToDate] == NO && sqlite3_open([[DB getDBPath:[NSString stringWithFormat:#"%#%#%#", #"Restaurant_V", [DB getVersion], #".sqlite" ]] UTF8String], [DB getDB]) == SQLITE_OK)
{
message = #"Mise à jour des données";
[DB setExecuting:YES];
[NSThread detachNewThreadSelector:#selector(createDB) toTarget:DB withObject:nil];
while([DB isExecuting]==YES)
{
if([DB isExecuting]==NO) break;
}
NSLog(#"Cas 1");
}
if([DB isCreated]== YES && [DB upToDate] == NO && sqlite3_open([[DB getDBPath:[NSString stringWithFormat:#"%#%#%#", #"Restaurant_V", [DB getVersion], #".sqlite" ]] UTF8String], [DB getDB]) == SQLITE_OK)
{
[DB setExecuting:YES];
[NSThread detachNewThreadSelector:#selector(updateDB:) toTarget:DB withObject:[DB getVersion]];
while([DB isExecuting]==YES)
{
if([DB isExecuting]==NO) break;
}
NSLog(#"Cas 2");
}
int p = floor([progress progress]*100);
while (pr<1.0)
{
p = floor(pr*100);
if(p%14==0)
{
CFRunLoopRunInMode (kCFRunLoopDefaultMode, 0, true);
[progress setProgress:pr];
[informations setText:[NSString stringWithFormat:#"%# (%d%#", message, p, #"%)"]];
}
pr += 0.000002;
}
[progress setProgress:1.0];
[informations setText:[NSString stringWithFormat:#"%# (100%#", message, #"%)"]];
menu =
[[[AC_Menu alloc] initWithNibName:#"AC_Menu_iPhone" bundle:nil] autorelease];
[self.navigationController pushViewController:menu animated:YES];
[DB release];
CLController = [[CoreLocationController alloc] init];
CLController.delegate = self;
[CLController.locMgr startUpdatingLocation];
}
- (void)dealloc {
[CLController release];
[logo release];
[informations release];
[progress release];
[super dealloc];
}

AlAssetsLibrary issue, code works in 4.3 but not 5.0

Here's my issue, if I access this class with iOS 4.X, the code works fine.... however whenever I try to access it with iOS 5.0, I get nil values for the groups & assets. What's the best way to get this to work? I'm posting the entire class for a reference...
.h
#import <UIKit/UIKit.h>
#import <AssetsLibrary/AssetsLibrary.h>
#import "DejViewController.h"
#class Event, Venue;
#interface SelectMediaViewController : DejViewController <UITableViewDelegate, UITableViewDataSource> {
Event *event;
Venue *venue;
UITableView *tableView;
NSMutableArray *selectedAssets;
NSMutableArray *allMedia;
ALAssetsLibrary *library;
NSMutableArray *assetGroups;
}
#property (nonatomic, retain) Event *event;
#property (nonatomic, retain) Venue *venue;
#property (nonatomic, retain) IBOutlet UITableView *tableView;
#property (nonatomic, retain) NSMutableArray *allMedia;
#property (nonatomic, retain) NSMutableArray *assetGroups;
- (IBAction)continuePressed:(id)sender;
#end
.m
#import <ImageIO/ImageIO.h>
#import "SelectMediaViewController.h"
#import "CaptionAllMediaViewController.h"
#import "MediaItem.h"
#import "CLValueButton.h"
#import "SelectMediaTableViewCell.h"
#define kMediaGridSize 75
#define kMediaGridPadding 4
#define kSelectImageTag 828
#interface SelectMediaViewController(Private)
- (void)setContentForButton:(CLValueButton *)button withAsset:(ALAsset *)asset;
- (void)loadData;
#end
#implementation SelectMediaViewController
#synthesize event, venue;
#synthesize tableView;
#synthesize allMedia,assetGroups;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
selectedAssets = [[NSMutableArray alloc] init];
showNextButton = YES;
}
return self;
}
- (void)dealloc {
[tableView release];
[event release];
[venue release];
[library release];
[allMedia release];
[selectedAssets release];
[assetGroups release];
[super dealloc];
}
- (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.
}
#pragma mark - View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"SelectMediaViewController - viewDidLoad");
}
- (void)viewDidUnload {
NSLog(#"SelectMediaViewController - viewDidUnload");
[self setTableView:nil];
[super viewDidUnload];
}
- (void)viewDidAppear:(BOOL)animated {
NSLog(#"SelectMediaViewController - viewDidAppear");
[super viewDidAppear:animated];
[self setNavTitle:#"Select Media"];
[self loadData];
[self.tableView reloadData];
float contentOffset = self.tableView.contentSize.height - self.tableView.frame.size.height;
if (contentOffset < 0) contentOffset = 0;
[self.tableView setContentOffset:CGPointMake(0, contentOffset) animated:NO];
}
- (void)viewDidDisappear:(BOOL)animated {
NSLog(#"SelectMediaViewController - viewDidDisappear");
self.allMedia = nil;
[selectedAssets removeAllObjects];
[self.tableView reloadData];
}
- (void)loadData {
NSMutableArray *tempArray = [[NSMutableArray array] init];
library = [[ALAssetsLibrary alloc] init];
void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
if(result != NULL) {
NSLog(#"See Asset: %#", result);
[tempArray addObject:result];
NSLog(#"assets count: %i", tempArray.count);
}
else {
NSLog(#"result nil or end of list");
}
};
void (^assetGroupEnumerator)(ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) {
if(group != nil) {
[group enumerateAssetsUsingBlock:assetEnumerator];
NSLog(#"group: %#",group);
}
else {
NSLog(#"group nil or end of list");
}
if (stop) {
self.allMedia = [NSMutableArray arrayWithCapacity:[tempArray count]];
self.allMedia = tempArray;
NSLog(#"Loaded data: %d & %d", [tempArray count], [self.allMedia count]);
}
};
//ALAssetsLibrary *library = [[[ALAssetsLibrary alloc] init] autorelease];
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos
usingBlock:assetGroupEnumerator
failureBlock:^(NSError *error) {
}];
//[library release];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (IBAction)continuePressed:(id)sender {
if ([selectedAssets count] > 0) {
CaptionAllMediaViewController *captionVC = [[CaptionAllMediaViewController alloc] initWithNibName:nil bundle:nil];
captionVC.event = self.event;
captionVC.venue = self.venue;
// Create media items
NSMutableArray *mediaItems = [NSMutableArray arrayWithCapacity:[selectedAssets count]];
for (ALAsset *asset in selectedAssets) {
MediaItem *item = [[MediaItem alloc] init];
item.asset = asset;
NSDictionary *metadata = [[asset defaultRepresentation] metadata];
NSDictionary *gpsMeta = [metadata objectForKey:#"{GPS}"];
if (gpsMeta) {
float latitude = [[gpsMeta objectForKey:#"Latitude"] floatValue];
if ([[gpsMeta objectForKey:#"LatitudeRef"] isEqualToString:#"S"]) latitude = latitude * -1;
float longitude = [[gpsMeta objectForKey:#"Longitude"] floatValue];
if ([[gpsMeta objectForKey:#"LongitudeRef"] isEqualToString:#"W"]) longitude = longitude * -1;
item.location = CLLocationCoordinate2DMake(latitude, longitude);
}
[mediaItems addObject:item];
[item release];
}
captionVC.media = mediaItems;
[self.navigationController pushViewController:captionVC animated:YES];
[captionVC release];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"No Images Selected"
message:#"Please select at least one image to continue."
delegate:nil
cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
[alert release];
}
}
- (void)imagePressed:(CLValueButton *)sender {
BOOL currentlySelected = [selectedAssets containsObject:sender.valueObject];
UIImageView *imageView = (UIImageView *)[sender viewWithTag:kSelectImageTag];
if (!currentlySelected) {
[imageView setImage:[UIImage imageNamed:#"image-select-active.png"]];
[selectedAssets addObject:sender.valueObject];
} else {
[imageView setImage:[UIImage imageNamed:#"image-select.png"]];
[selectedAssets removeObject:sender.valueObject];
}
}
#pragma Table view methods
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"Getting table view count: %d", [self.allMedia count]);
if ([self.allMedia count] == 0) return 0;
return ceil([self.allMedia count] / 4.0);
}
- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 83;
NSLog(#"return83");
}
- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
SelectMediaTableViewCell *cell = (SelectMediaTableViewCell *)[_tableView dequeueReusableCellWithIdentifier:#"MEDIA_CELL"];
if (!cell) {
cell = [[[NSBundle mainBundle] loadNibNamed:#"SelectMediaTableViewCell" owner:nil options:nil] objectAtIndex:0];
// wire up selectors
[cell.image1 addTarget:self action:#selector(imagePressed:) forControlEvents:UIControlEventTouchUpInside];
[cell.image2 addTarget:self action:#selector(imagePressed:) forControlEvents:UIControlEventTouchUpInside];
[cell.image3 addTarget:self action:#selector(imagePressed:) forControlEvents:UIControlEventTouchUpInside];
[cell.image4 addTarget:self action:#selector(imagePressed:) forControlEvents:UIControlEventTouchUpInside];
}
int startIndex = indexPath.row * 4;
for (int i = 0; i < 4; i++) {
ALAsset *thisAsset = (startIndex + i) < [self.allMedia count] ? [self.allMedia objectAtIndex:startIndex + i] : nil;
CLValueButton *button = nil;
switch (i) {
case 0:
button = cell.image1;
break;
case 1:
button = cell.image2;
break;
case 2:
button = cell.image3;
break;
case 3:
button = cell.image4;
break;
default:
break;
}
[self setContentForButton:button withAsset:thisAsset];
UIImageView *imageView = (UIImageView *)[button viewWithTag:kSelectImageTag];
// letse see if it's selected or not...
if ([selectedAssets containsObject:button.valueObject]) {
[imageView setImage:[UIImage imageNamed:#"image-select-active.png"]];
} else {
[imageView setImage:[UIImage imageNamed:#"image-select.png"]];
}
}
return cell;
}
- (void)setContentForButton:(CLValueButton *)button withAsset:(ALAsset *)asset {
button.hidden = asset == nil;
if (asset) {
CGImageRef image = [asset thumbnail];
[button setImage:[UIImage imageWithCGImage:image] forState:UIControlStateNormal];
}
[button setValueObject:asset];
}
#pragma -
#end
Any help would be much appreciated, I've been trying to figure this out for 3 days...
The ALAssetsLibrary page in the online documentation now says "The lifetimes of objects you get back from a library instance are tied to the lifetime of the library instance."

plist segment control save issue

I have a issue with this peice of code, I am trying to save some data to a plist for later use, and if the user reopens the view, it should have the current segment selected for each segment control on my view.
however when I try and save the information, it crashes on the line
[array addObject:gender];
please help :) it gives EXC_BAD_ACCESS
-(IBAction)genderSelection:(id)sender
{
if([sender selectedSegmentIndex] == kSwitchesSegmentIndex)
{
gender = #"Male";
//NSLog(gender);
}
else {
gender = #"Female";
//NSLog(gender);
}
}
-(IBAction)contactTypeSelection:(id)sender
{
if([sender selectedSegmentIndex] == kSwitchesSegmentIndex)
{
contactType = #"a";
//NSLog(gender);
}
else {
contactType = #"b";
//NSLog(gender);
}
}
-(IBAction)saveData:(id)sender
{
NSMutableArray *array = [[NSMutableArray alloc] init];
[array removeAllObjects];
[array addObject:field1.text];
[array addObject:field2.text];
[array addObject:gender];
[array addObject:contactType];
[array writeToFile:[self dataFilePath] atomically:YES];
[array release];
}
-(NSString *)dataFilePath
{
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [path objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:kFilename];
}
-(void)viewWillAppear:(BOOL)animated
{
NSString *filePath = [self dataFilePath];
if([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
NSArray *array = [[NSArray alloc] initWithContentsOfFile:filePath];
field1.text = [array objectAtIndex:0];
field2.text = [array objectAtIndex:1];
gender = [array objectAtIndex:2];
contactType = [array objectAtIndex:3];
if([gender isEqualToString:#"Male"])
{
genderSegment.selectedSegmentIndex = 0;
}
else
{
genderSegment.selectedSegmentIndex = 1;
}
if([contactType isEqualToString:#"a"])
{
}
else
{
}
[array release];
}
}
-(IBAction)textDone:(id)sender
{
[sender resignFirstResponder];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[gender release]; //need to release
[contactType release]; //need to release
[field1 release]; //need to release
[field2 release]; //need to release
[super dealloc];
}
- (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.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
gender = #"Male";
contactType = #"a";
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
gender = nil; //need to release
contactType = nil; //need to release
field1 = nil ; //need to release
field2 = nil; //need to release
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
You didn't didn't initialize your gender property. You need:
- (void)viewDidLoad
{
    [super viewDidLoad];
self.gender=[[NSString alloc]init];
    self.gender = #"Male";
//so something here
    // Do any additional setup after loading the view from its nib.
}
NOTE: If you use the #synthesize compiler directive then you need to the self-dot notation everywhere to refer to the property e.g. self.gender.