How to add a textfield to an NSMutableArray - ios

I'm trying to present what was entered into a textfield into a nsmutable array that will later be displayed.
I think that the problem is in the -(void)viewDidLoad method but I included all of the code just in case. The catch is that I will be leaving this page and then returning to it after another piece of information is selected. As this happens, I need to keep track of EACH thing that was entered into the textfield. Thanks for any help!
#import "EnteringCoursesViewController.h"
#import "SelectRotationController.h"
#implementation EnteringCoursesViewController
#synthesize classField;
#synthesize indicatedClass;
#synthesize labelClassTitle;
#synthesize selectRotationController;
#synthesize classesEnteredTable;
- (IBAction)chooseType {
UIActionSheet *typeSheet = [[UIActionSheet alloc]
initWithTitle:#"Class types"
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:#"Core Class", #"Elective", nil];
[typeSheet showInView:self.view];
[typeSheet release];
}
- (void)actionSheet:(UIActionSheet *)typeSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0) {
self.indicatedClass = classField.text;
NSString *indicatedString = indicatedClass;
NSString *greeting = [[NSString alloc]
initWithFormat:#"%# meets 6 times per rotation", indicatedString];
labelClassTitle.text = greeting;
labelClassTitle.hidden = NO;
[greeting release];
[indicatedClass release];
}
else if (buttonIndex == 1) {
self.indicatedClass = classField.text;
NSString *indicatedString = indicatedClass;
NSString *greeting = [[NSString alloc]
initWithFormat:#"%# meets 3 times per rotation", indicatedString];
labelClassTitle.text = greeting;
labelClassTitle.hidden = NO;
[greeting release];
[indicatedClass release];
}
}
- (IBAction)chooseFirstMeeting:(id)sender {
SelectRotationController *selectView = [[SelectRotationController alloc]
initWithNibName:#"SelectRotationController"
bundle:[NSBundle mainBundle]];
[selectView.navigationItem setTitle:#"First Period Day Choose"];
[self.navigationController pushViewController:self.selectRotationController animated:YES];
self.selectRotationController = selectView;
[selectView release];
}
- (IBAction)enteredClassText:(id)sender {
NSMutableArray *classesEntered = [[NSMutableArray alloc] init];
[classesEntered addObject:indicatedClass];
[classesEntered release];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidLoad {
self.navigationItem.hidesBackButton = YES;
[super viewDidLoad];
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[classField release];
[labelClassTitle release];
[indicatedClass release];
[selectRotationController release];
[classesEnteredTable release];
[super dealloc];
}
#end

If viewDidLoad is called "indicatedClass" is not yet initialised and therefore nil.
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSMutableArray_Class/Reference/Reference.html
Important Raises an NSInvalidArgumentException if anObject is nil.
If you want to save that by leaving the view, add the addObject-Call in the viewDidUnload-method. Definitely you should check if the value is nil ;)
I dont see any alloc for your variable indicatedClass but an release!? It might be that the variable doesnt exists if viewDidUnload is calling.
EDIT
You init an NSMutableArray, add the object to this array and after that you released that object. Therefore the Data is away. You must save your array therewith you can use the content later. Keyword: NSUserDefaults ;)
Check also of nil values:
- (IBAction)enteredClassText:(id)sender {
if (indicatedClass != nil) {
NSMutableArray *classesEntered = [[NSMutableArray alloc] init];
[classesEntered addObject:indicatedClass];
[classesEntered release];
}
}
If the sender is an UILabel you can also use this snippet:
- (IBAction)enteredClassText:(id)sender {
if (sender.text != nil) {
NSMutableArray *classesEntered = [NSMutableArray arrayWithObject:sender.text];
// TODO: Save your array to NSUserDefaults...
}
}

Related

iOS: Crash after writing socket

In my application, I am sending screenshot of the current view programmatically and sending to a socket server program at every 5 seconds interval.
Socket program is running in Eclipse. I checked the code earlier and able to send screenshot of the image to the socket without any issues.
After that, as per my actual requirement, I added a tab bar controller (5 tabs) and used navigation controller for the first tab selection. As per my code below, the first tab bar item is “MyHomeViewController”.
In the “MyHomeViewController” i have a button action called -(IBAction)goAhead:(id)sender. Clicking on this will take to another “HomeViewController”.
In this “HomeViewController”, I connect socket and if the socket connection is success, under “NSStreamEventHasSpaceAvailable” delegate method, i call a function called “[self coShareScreen];” to take to sending screenshot images of the current view (whatever view controller is present) and sending to that socket server program.
I use a “CobrowseSingletonSocket” class, where i have socket related variables and sending screenshot programmatically are handled in this function “-(void) takeScreenshotSend :(NSString *) endOrCancelString”.
My issue is, socket is getting connected successfully now. It should send screenshot of the image programmatically wherever the view I’m currently in.
As expected, Its start sending the screenshot of the view programmatically to socket server successfully at every 5 seconds interval.
But,
As its a navigation controller based view, If i coming back to the first view manually, which is “MyHomeViewController”. It tries to send that screen also, but it crashes after immediately write socket is done.
It is crashing immediately after writing here-> “int num = [self.outputStream write:[data bytes] maxLength:([data length])];”
This is crash is happening only if i come back in navigation controller manually. If i stay in “HomeViewController” itself after socket connection, it keeps sending screenshot programmatically a t every 5 seconds interval to socket server without any issues.
I don’t understand what could be the reason here? Please someone advise me, as i’m unable to fix this for long time. Please also let me know if i need to paste any more code here.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
UITabBarController *tabbarCtrler = [[UITabBarController alloc]init];
MyHomeViewController *myHomeCtrler = [[MyHomeViewController alloc] initWithNibName:#"MyHomeViewController" bundle:NULL];
[myHomeCtrler.tabBarItem setTitle:#"My Home"];
ProductsViewController *prodViewCtrler = [[ProductsViewController alloc] initWithNibName:#"ProductsViewController" bundle:NULL];
[prodViewCtrler.tabBarItem setTitle:#"Products"];
InboxViewController *inboxViewCtrler = [[InboxViewController alloc] initWithNibName:#"InboxViewController" bundle:NULL];
[inboxViewCtrler.tabBarItem setTitle:#"Inbox"];
ContactUSViewController *contactViewCtrler = [[ContactUSViewController alloc] initWithNibName:#"ContactUSViewController" bundle:NULL];
[contactViewCtrler.tabBarItem setTitle:#"Contact Us"];
VoiceViewController *voiceViewCtrler = [[VoiceViewController alloc] initWithNibName:#"VoiceViewController" bundle:NULL];
[voiceViewCtrler.tabBarItem setTitle:#"Voice"];
UINavigationController *navigationcontroller = [[UINavigationController alloc] initWithRootViewController:myHomeCtrler];
navigationcontroller.title = #"My News;
[navigationcontroller.navigationBar setBackgroundImage:[UIImage imageNamed:#"SettingsTitlebar.png"] forBarMetrics:UIBarMetricsDefault];
[navigationcontroller setNavigationBarHidden:YES];
//create an array of all view controllers that will represent the tab at the bottom
NSArray *arrayViewControllers = [[NSArray alloc] initWithObjects:
navigationcontroller, prodViewCtrler, inboxViewCtrler, contactViewCtrler, voiceViewCtrler, nil];
[tabbarCtrler setViewControllers:arrayViewControllers];
[self.window makeKeyAndVisible];
[self.window setRootViewController:tabbarCtrler];
return YES;
}
and
#import "MyHomeViewController.h"
#import "SettingsViewController.h"
#interface MyHomeViewController ()
#end
#implementation MyHomeViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(IBAction)goAhead:(id)sender
{
HomeViewController *homeViewController = [[HomeViewController alloc] initWithNibName:#"HomeViewController" bundle:nil];
[self.navigationController pushViewController:setttingsViewController animated:YES];
}
and
// HomeViewController.m
//
//
#import "HomeViewController.h"
#import "AppDelegate.h"
#import "CobrowseSingletonSocket.h"
#import <QuartzCore/QuartzCore.h>
#import <notify.h>
#interface HomeViewController ()
#end
#implementation HomeViewController
#synthesize authTexField;
#synthesize sessionID;
#synthesize sentPing;
#synthesize bScreenOff;
#synthesize responseAlertView;
#synthesize portFld;
#synthesize ipFld;
#synthesize shareScreenTimer;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
authTexField.delegate = self;
responseAlertView.delegate = self;
ipFld.delegate = self;
portFld.delegate = self;
bScreenOff = NO;
cobrowseSingletonIns = [CobrowseSingletonSocket sharedCobrowseSocketInstance];
}
-(void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:NO];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(IBAction)connectShare:(id)sender
{
// Connect socket freshly here
[self initSocketConnection];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
- (IBAction)backAction:(id)sender
{
[self dismissModalViewControllerAnimated:YES];
}
#pragma mark Socket Connection
- (void)initSocketConnection
{
NSString * ipAddrStr = ipFld.text;
NSString * portStr = portFld.text;
NSLog(#"IPAddress: %# ; Port: %#", ipAddrStr, portStr);
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
NSString *ipaddress = ipAddrStr;
ipaddress = [ipaddress stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSLog(#"Retrieved socket ip: %#", cobrowseSingletonIns.socketIPAddress);
CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)ipaddress, 8081, &readStream, &writeStream);
cobrowseSingletonIns.inputStream = (__bridge_transfer NSInputStream *)readStream;
cobrowseSingletonIns.outputStream = (__bridge_transfer NSOutputStream *)writeStream;
[cobrowseSingletonIns.inputStream setDelegate:self];
[cobrowseSingletonIns.outputStream setDelegate:self];
[cobrowseSingletonIns.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[cobrowseSingletonIns.outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[cobrowseSingletonIns.inputStream open];
[cobrowseSingletonIns.outputStream open];
}
-(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent
{
NSString *io;
if (theStream == cobrowseSingletonIns.inputStream) io = #">>";
else io = #"<<";
NSLog(#"Stream space : %d",[cobrowseSingletonIns.outputStream hasSpaceAvailable]);
NSString *event;
switch (streamEvent)
{
case NSStreamEventNone:
event = #"NSStreamEventNone";
//statusText.text = #"Can not connect to the host!";
NSLog(#"NSStreamEventNone - Can not connect to the host");
break;
case NSStreamEventOpenCompleted:
event = #"NSStreamEventOpenCompleted";
//pingButton.hidden = NO;
//statusText.text = #"Connected";
NSLog(#"Connected");
break;
case NSStreamEventHasBytesAvailable:
event = #"NSStreamEventHasBytesAvailable";
NSLog(#"NSStreamEventHasBytesAvailable called");
if (theStream == cobrowseSingletonIns.inputStream)
{
//read data
//uint8_t buffer[1024];
uint8_t buffer[2];
NSMutableData *data=[[NSMutableData alloc] init];
int len;
while ([cobrowseSingletonIns.inputStream hasBytesAvailable])
{
len = [cobrowseSingletonIns.inputStream read:buffer maxLength:sizeof(buffer)];
if(len)
{
[data appendBytes:&buffer length:len];
}
else
{
NSLog(#"no buffer!");
}
}
NSString *responseStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
responseStr = [responseStr stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
//do something with data
NSLog(#"Server said this-> %#", responseStr);
NSString *successResponse;
responseAlertView = [[UIAlertView alloc] init];
if ( [responseStr isEqualToString:#"SUCCESS"])
{
successResponse = #"Successfully connected! Click OK to starts screen sharing!";
responseAlertView.tag = 3;
[responseAlertView addButtonWithTitle:#"OK"];
[responseAlertView addButtonWithTitle:#"CANCEL"];
}
else
{
successResponse = #"There seems to be problem in connecting..Try connecting it again with proper Random Auth ID!";
responseAlertView.tag = 4;
[responseAlertView addButtonWithTitle:#"OK"];
}
responseAlertView.delegate = self;
[responseAlertView setTitle:#"Cobrowsing"];
[responseAlertView setMessage:successResponse];
[responseAlertView show];
}
break;
case NSStreamEventHasSpaceAvailable:
{
event = #"NSStreamEventHasSpaceAvailable";
NSLog(#"space : %d", [cobrowseSingletonIns.outputStream hasSpaceAvailable]);
if ( !cobrowseSingletonIns.bConnectionEstablished )
{
NSLog(#"NSStreamEventHasSpaceAvailable - Connection established, sharing is going to be established!");
if ( theStream == cobrowseSingletonIns.outputStream && !self.sentPing )
{
if ( [sessionID length]<=0 )
sessionID = #"EMPTY";
NSLog(#"sessionID : %#", sessionID);
NSData* data = [sessionID dataUsingEncoding:NSUTF8StringEncoding];
int num = [cobrowseSingletonIns.outputStream write:[data bytes] maxLength:([data length])];
if (-1 == num) {
NSLog(#"Error writing to stream %#: %#", cobrowseSingletonIns.outputStream, [cobrowseSingletonIns.outputStream streamError]);
}else{
NSLog(#"Wrote %i bytes to stream %#.", num, cobrowseSingletonIns.outputStream);
}
sentPing = YES;
}
}
else
{
NSLog(#"NSStreamEventHasSpaceAvailable - Connection already established");
if ( [cobrowseSingletonIns.outputStream hasSpaceAvailable] )
{
[self coShareScreen];
}
}
}
break;
case NSStreamEventErrorOccurred:
{
event = #"NSStreamEventErrorOccurred";
NSLog(#"NSStreamEventErrorOccurred - Can not connect to the host");
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Co-browsing" message:#"Connection error, Cannot connect to the host!" delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
alertView.tag = 5;
[alertView show];
}
break;
case NSStreamEventEndEncountered:
event = #"NSStreamEventEndEncountered";
NSLog(#"NSStreamEventEndEncountered - Connection closed by the server");
break;
default:
event = #"** Unknown";
}
NSLog(#"%# : %#", io, event);
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
int tag = alertView.tag;
NSLog(#"buttonIndex: %d ; alertView.tag: %d", buttonIndex, tag);
if ( alertView.tag==3 )
{
if ( buttonIndex==0 ) // for OK button
{
sentPing = NO;
cobrowseSingletonIns.bConnectionEstablished = YES;
[cobrowseSingletonIns shareScreen]; // call just once here, then 5 mins thread caller will be called in hasspaceavailable delegate method.
}
else if ( buttonIndex==1 ) // for Cancel button
{
NSLog(#"User selected Cancel, just stop the socket connection");
[cobrowseSingletonIns.outputStream close];
[cobrowseSingletonIns.outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
}
else if (alertView.tag==4)
{
NSLog(#"Problem connecting with socket, just stop the socket connection");
sentPing = NO;
[cobrowseSingletonIns.outputStream close];
[cobrowseSingletonIns.outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
else if (alertView.tag==5) // Socket connection closed Abruptly, one of the reasons, user manually locked of the phone. In this case, logout and love to login
{
NSLog(#"Socket connection closed Abruptly due to unknown reasons");
}
}
//-(void) shareScreen :(NSTimer *) timerInfo
-(void) coShareScreen
{
NSLog(#"coShareScreen called");
[cobrowseSingletonIns shareScreen];
}
#end
and
//
// CobrowseSingletonSocket.m
//
#import "CobrowseSingletonSocket.h"
#import "AppDelegate.h"
#import "MyUSAAViewController.h"
#import "USAASettingsViewController.h"
#import "ProductsViewController.h"
#import "InboxViewController.h"
#import "ContactUSViewController.h"
#import "VoiceViewController.h"
#import <QuartzCore/QuartzCore.h>
#implementation CobrowseSingletonSocket
static CobrowseSingletonSocket *sharedCobrowseSocketInstance = nil;
#synthesize loginViewController;
#synthesize outputStream;
#synthesize inputStream;
#synthesize bConnectionEstablished;
#synthesize socketIPAddress;
#synthesize servletIPAddress;
#synthesize servletPort;
+(CobrowseSingletonSocket *) sharedCobrowseSocketInstance
{
#synchronized ([CobrowseSingletonSocket class])
{
if ( !sharedCobrowseSocketInstance )
{
sharedCobrowseSocketInstance = [[super allocWithZone:NULL] init];
}
}
return sharedCobrowseSocketInstance;
}
+ (id)allocWithZone:(NSZone *)zone
{
return [self sharedCobrowseSocketInstance];
}
-(void) takeScreenshotSend :(NSString *) endOrCancelString
{
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
UIGraphicsBeginImageContext(appDelegate.window.bounds.size);
[appDelegate.window.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSMutableData *data = [NSMutableData data];
data = (NSMutableData *) UIImagePNGRepresentation(image);
//[data writeToFile:#"screenshot.png" atomically:YES];
NSLog(#"shareScreen [data length] %i: ", [data length]);
NSData *newData = [endOrCancelString dataUsingEncoding:NSUTF16StringEncoding];
[data appendData:newData];
NSLog(#"shareScreen [data length] %i: ", [data length]);
//sentPing = YES;
int num = [self.outputStream write:[data bytes] maxLength:([data length])];
if (-1 == num) {
NSLog(#"Error writing to stream %#: %#", self.outputStream, [self.outputStream streamError]);
}else{
NSLog(#"Wrote %i bytes to stream %#.", num, self.outputStream);
//[self.outputStream close];
}
}
-(void) shareScreenAtInterval
{
NSLog(#"Screen sharing going to happen!");
[self takeScreenshotSend:#"END"]; // appending END, to detect the same on the server side and get out of reading data loop there.
}
-(void) shareScreen
{
NSLog(#"shareScreen called!");
[self performSelector:#selector(shareScreenAtInterval) withObject:nil afterDelay:5.0];
}
-(void) disconnectSocket
{
NSLog(#"Close the socket connection by user");
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(shareScreenAtInterval) object: nil];
//[NSObject cancelPreviousPerformRequestsWithTarget:self];
// Send Cancel message to socket
[self takeScreenshotSend:#"CANCEL"]; // appending CANCEL, to detect the same on the server side and get out of reading data loop there.
[self.outputStream close];
[self.outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
self.outputStream = nil;
self.bConnectionEstablished = NO;
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Co-browsing" message:#"Screen sharing disconnected!" delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alertView show];
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
[appDelegate.window.rootViewController dismissModalViewControllerAnimated:YES];
}
#end
Crash error in Xcode
Your problem is here -
[cobrowseSingletonIns.inputStream setDelegate:self];
[cobrowseSingletonIns.outputStream setDelegate:self]
Your HomeViewController sets itself as the delegate for the socket, but once it has been removed from view it will be deallocated, because the delegate property on the streams will be a weak reference.
You need to make sure the socket writing is completed and cleaned up when the view controller is removed. Try setting the delegates to nil in viewWillDisappear.

Saving pictures to parse

My project will save data to parse and while I can pick an image from my library I cannot open the camera. I found a tutorial to do this but it is not compatible with my code. The link to the tutorial is here: Tutorial . I am using .storyboard and the tutorial is .xib, I do not know if this will change anything.
my .m file is here:
#import "NewRecipeViewController.h"
#import <MobileCoreServices/UTCoreTypes.h>
#import <Parse/Parse.h>
#import "MBProgressHUD.h"
#interface NewRecipeViewController ()
- (IBAction)save:(id)sender;
- (IBAction)cancel:(id)sender;
#property (weak, nonatomic) IBOutlet UIImageView *recipeImageView;
#property (weak, nonatomic) IBOutlet UITextField *nameTextField;
#property (weak, nonatomic) IBOutlet UITextField *prepTimeTextField;
#property (weak, nonatomic) IBOutlet UITextField *ingredientsTextField;
#end
#implementation NewRecipeViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_nameTextField.delegate = self;
_prepTimeTextField.delegate = self;
_ingredientsTextField.delegate = self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
[self showPhotoLibary];
}
}
- (void)showPhotoLibary
{
if (([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypeSavedPhotosAlbum] == NO)) {
return;
}
UIImagePickerController *mediaUI = [[UIImagePickerController alloc] init];
mediaUI.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
// Displays saved pictures from the Camera Roll album.
mediaUI.mediaTypes = #[(NSString*)kUTTypeImage];
// Hides the controls for moving & scaling pictures
mediaUI.allowsEditing = NO;
mediaUI.delegate = self;
[self.navigationController presentModalViewController: mediaUI animated: YES];
}
- (IBAction)save:(id)sender {
// Create PFObject with recipe information
PFObject *recipe = [PFObject objectWithClassName:#"Recipe"];
[recipe setObject:_nameTextField.text forKey:#"name"];
[recipe setObject:_prepTimeTextField.text forKey:#"prepTime"];
NSArray *ingredients = [_ingredientsTextField.text componentsSeparatedByString: #","];
[recipe setObject:ingredients forKey:#"ingredients"];
// Recipe image
NSData *imageData = UIImageJPEGRepresentation(_recipeImageView.image, 0.8);
NSString *filename = [NSString stringWithFormat:#"%#.png", _nameTextField.text];
PFFile *imageFile = [PFFile fileWithName:filename data:imageData];
[recipe setObject:imageFile forKey:#"imageFile"];
// Show progress
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.mode = MBProgressHUDModeIndeterminate;
hud.labelText = #"Uploading";
[hud show:YES];
// Upload recipe to Parse
[recipe saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
[hud hide:YES];
if (!error) {
// Show success message
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Upload Complete" message:#"Successfully saved the recipe" delegate:Nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
// Notify table view to reload the recipes from Parse cloud
[[NSNotificationCenter defaultCenter] postNotificationName:#"refreshTable" object:self];
// Dismiss the controller
[self dismissViewControllerAnimated:YES completion:nil];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Upload Failure" message:[error localizedDescription] delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
}];
}
- (IBAction)cancel:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)viewDidUnload {
[self setRecipeImageView:nil];
[self setNameTextField:nil];
[self setPrepTimeTextField:nil];
[self setIngredientsTextField:nil];
[super viewDidUnload];
}
- (void) imagePickerController: (UIImagePickerController *) picker didFinishPickingMediaWithInfo: (NSDictionary *) info {
UIImage *originalImage = (UIImage *) [info objectForKey:UIImagePickerControllerOriginalImage];
self.recipeImageView.image = originalImage;
[picker dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - Textfield delegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
- (IBAction)takephoto:(id)sender {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker animated:YES completion:NULL];
}
- (IBAction)selectphoto:(id)sender {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:picker animated:YES completion:NULL];
}
#end
Any help is appreciated.
Take a look at Apple's provided sample project (especially APLViewController.m)
https://developer.apple.com/library/ios/samplecode/PhotoPicker/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010196
You'll see them do the following 4 steps. You are only doing the last half of step one, without first verifying if that source type is even available.
From the UIImagePickerController Class Reference:
To use an image picker controller containing its default controls, perform these steps:
Verify that the device is capable of picking content from the desired source. Do this calling the isSourceTypeAvailable: class method, providing a constant from the “UIImagePickerControllerSourceType” enumeration.
Check which media types are available, for the source type you’re using, by calling the availableMediaTypesForSourceType: class method. This lets you distinguish between a camera that can be used for video recording and one that can be used only for still images.
Tell the image picker controller to adjust the UI according to the media types you want to make available—still images, movies, or both—by setting the mediaTypes property.
Present the user interface. On iPhone or iPod touch, do this modally (full-screen) by calling the presentViewController:animated:completion: method of the currently active view controller, passing your configured image picker controller as the new view controller.

Clean array by using delegate

I made an AR app that recognize image and show the object recognized in an AlertView. In the AlertView I have 2 buttons: Add and Cancel, I'm using the UIAlertViewDelegate to understand which button the user pressed. If the user press the Add button, the object recognized will be stored in an array. I pass this array to another ViewController, in which I set up a TableView. On the bottom of this TableView there's a button "Pay" to go to another ViewController in which I display the total price of the object recognized. From the last ViewController I can press a button to pay the objects I selected by using the AR. Now when I press this button the app close this ViewController and go back to the first ViewController, but the array in which I stored the object that the AR recognized it's full. To delete the content of this array I thought that the best way is to use the delegation methods, so I made this:
PaymentViewController.h
#import <UIKit/UIKit.h>
#protocol PaymentViewControllerDelegate;
#interface PaymentViewController : UIViewController
#property (strong, nonatomic) IBOutlet UILabel *labelTotal;
- (IBAction)buttonClosePaymentVC:(id)sender;
- (IBAction)buttonPay:(id)sender;
#property(nonatomic,strong)NSString *total;
#property(assign) id<PaymentViewControllerDelegate> delegate;
#end
#protocol PaymentViewControllerDelegate <NSObject>
- (void)cleanReportArray;
#end
PaymentViewController.m
#import "PaymentViewController.h"
#interface PaymentViewController () <UIAlertViewDelegate>
#end
#implementation PaymentViewController
#synthesize delegate = _delegate;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.labelTotal.text = self.total;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)buttonClosePaymentVC:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)buttonPay:(id)sender {
NSString *pay = [NSString stringWithFormat:#"Stai per pagare %#, procedi?", self.total];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"HelloMS" message:pay delegate:self cancelButtonTitle:#"Si" otherButtonTitles:#"No", nil];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
// Procedura per il pagamento e cancellazione del file plist
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"objects.plist"];
NSError *error;
if (![[NSFileManager defaultManager]removeItemAtPath:path error:&error]) {
NSLog(#"Errore: %#", error);
}
__weak UIViewController *vcThatPresentedCurrent = self.presentingViewController;
[self dismissViewControllerAnimated:YES completion:^{
[vcThatPresentedCurrent dismissViewControllerAnimated:YES completion:nil];
}];
[self.delegate cleanReportArray];
}
if (buttonIndex == 1) {
// Non deve far nulla: fa scomparire l'UIAlertView
}
}
Here I post to you the method of the class that will use the delegate:
Interface of the ScannerViewController.m
#interface ScannerViewController () <MSScannerSessionDelegate, PaymentViewControllerDelegate, UIActionSheetDelegate, UIAlertViewDelegate>
#property (weak) IBOutlet UIView *videoPreview;
- (IBAction)stopScanner:(id)sender;
#end
In ViewDidLoad I inserted this rows:
PaymentViewController *pay = [[PaymentViewController alloc]init];
[pay setDelegate:self];
And in the ScannerViewController.m I implemented the method I declared in PaymentViewController.h:
- (void)cleanReportArray {
[arrayObjectAdded removeAllObjects];
}
I tested my app on my iPhone, the app works fine until I try to pay the objects I scanned by camera, indeed, I tried to pay the object, but it doesn't clean the array in which I stored the objects scanned.
What's wrong in my code? I used an tutorial on the web to understand better how the delegation method works. I hope you can help me to fix this issue, thank you
UPDATE:
here i will post my ScannerViewController code:
ScannerViewController.h
#import <UIKit/UIKit.h>
#interface ScannerViewController : UIViewController
#end
ScannerViewController.m
#import "ScannerViewController.h"
#import "PaymentViewController.h"
#import "ReportViewController.h"
#import "MSScannerSession.h"
#import "MSResult.h"
#import "XmlReader.h"
static int kMSScanOptions = MS_RESULT_TYPE_IMAGE |
MS_RESULT_TYPE_EAN8 |
MS_RESULT_TYPE_EAN13;
#interface ScannerViewController () <MSScannerSessionDelegate, PaymentViewControllerDelegate, UIActionSheetDelegate, UIAlertViewDelegate>
#property (weak) IBOutlet UIView *videoPreview;
- (IBAction)stopScanner:(id)sender;
#end
#implementation ScannerViewController {
MSScannerSession *_scannerSession;
NSString *nameOfObjectScanned;
XmlReader *reader;
NSMutableArray *arrayObjectAdded;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
_scannerSession = [[MSScannerSession alloc] initWithScanner:[MSScanner sharedInstance]];
[_scannerSession setScanOptions:kMSScanOptions];
[_scannerSession setDelegate:self];
}
return self;
}
- (void)session:(MSScannerSession *)scanner didScan:(MSResult *)result {
if (!result) {
return;
}
[_scannerSession pause];
NSString *resultStr = nil;
if (result) {
switch ([result getType]) {
case MS_RESULT_TYPE_IMAGE:
resultStr = [NSString stringWithFormat:#"Immagine trovata: %#", [result getValue]];
break;
case MS_RESULT_TYPE_EAN8:
case MS_RESULT_TYPE_EAN13:
resultStr = [NSString stringWithFormat:#"EAN trovato: %#", [result getValue]];
break;
default:
break;
}
}
dispatch_async(dispatch_get_main_queue(), ^{
UIActionSheet *asView = [[UIActionSheet alloc]initWithTitle:resultStr delegate:self cancelButtonTitle:#"OK" destructiveButtonTitle:nil otherButtonTitles:nil, nil];
asView.actionSheetStyle = UIActionSheetStyleBlackTranslucent;
[asView showInView:self.view];
[self addObjectToList:resultStr];
});
}
- (void)addObjectToList:(NSString *)objectName {
// Ricerca dell'oggetto
NSString *object = [objectName substringFromIndex:18];
if ([object isEqualToString:#"Binario_con_coppia"]) {
[self showAlert:object];
}
if ([object isEqualToString:#"Dadi_colorati"]) {
[self showAlert:object];
}
if ([object isEqualToString:#"Dadi_rossi"]) {
[self showAlert:object];
}
if ([object isEqualToString:#"Bici_da_corsa"]) {
[self showAlert:object];
}
}
- (void)showAlert:(NSString*)name {
name = [name stringByReplacingOccurrencesOfString:#"_" withString:#" "];
nameOfObjectScanned = name;
NSString *message = [NSString stringWithFormat:#"Ho riconosciuto questo oggetto: %#, vuoi aggiungerlo al carrello?", name];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"HelloMS" message:message delegate:self cancelButtonTitle:#"Aggiungi" otherButtonTitles:#"Annulla", nil];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
NSLog(#"Aggiungi");
for (int i = 0; i < [reader.objArray count]; i++) {
if ([[reader.objArray[i]objectForKey:#"name"] isEqualToString:nameOfObjectScanned]) {
// Salvo il nome dell'oggetto trovato, il prezzo e la descrizione
NSString *name = [reader.objArray[i]objectForKey:#"name"];
NSString *desc = [reader.objArray[i]objectForKey:#"desc"];
NSString *price = [reader.objArray[i]objectForKey:#"price"];
NSDictionary *newObjectAdded = [[NSDictionary alloc]init];
newObjectAdded = #{#"name": name,
#"desc": desc,
#"price": price};
[arrayObjectAdded addObject:newObjectAdded];
}
}
} else {
NSLog(#"Annulla");
}
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
[_scannerSession resume];
}
- (void)viewDidLoad
{
[super viewDidLoad];
arrayObjectAdded = [[NSMutableArray alloc]init];
CALayer *videoPreviewLayer = [self.videoPreview layer];
[videoPreviewLayer setMasksToBounds:YES];
CALayer *captureLayer = [_scannerSession previewLayer];
[captureLayer setFrame:[self.videoPreview bounds]];
[videoPreviewLayer insertSublayer:captureLayer below:[[videoPreviewLayer sublayers] objectAtIndex:0]];
reader = [[XmlReader alloc]init];
[reader parseXml];
[_scannerSession startCapture];
PaymentViewController *pay = [[PaymentViewController alloc]init];
[pay setDelegate:self];
}
- (void)cleanReportArray {
[arrayObjectAdded removeAllObjects];
}
- (void)dealloc {
[_scannerSession stopCapture];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)stopScanner:(id)sender {
ReportViewController *reportVC = [[ReportViewController alloc]initWithNibName:#"ReportViewController" bundle:nil];
reportVC.reportArray = arrayObjectAdded;
[reportVC setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self presentViewController:reportVC animated:YES completion:nil];
}
#end
To recognize picture I'm using this AR SDK. I hope you can help me to understand where's my issue
Your problem is that in viewDidLoad you have the code:
PaymentViewController *pay = [[PaymentViewController alloc]init];
[pay setDelegate:self];
this is the last thing you do in that method. So the instance of PaymentViewController that you create and set the delegate on is immediately destroyed (by ARC).
You need to modify your code so that you call setDelegate: on the actual instance of PaymentViewController that is presented on screen as this is the instance that needs to use the delegate (it receives the callback from the alert view).

validation method doesn't gets called and segue doesn't gets triggered

I am trying to implement a sign up process with a parse backend. I have a validation method called processFieldEntries and once the done button gets enabled, I try to trigger the segue that I setup modally from my view controller(not from the done button) from view did appear method but neither the validation method gets called nor the segue gets triggered. I setup some debug and logging breakpoints for debugging but, I couldn't go any further apart from the fact that it does not see the view did load. I also tried setting up the segue from the done button. When I did that, the segue gets triggered, not from the code but from storyboard my storyboard here. If someone can help me to figure out how to call processfieldentriees along with the segue, I would really appreciate. Thank you.
NewUserSignUpViewController.h
#import <UIKit/UIKit.h>
#import "ProfileViewController.h"
#interface NewUserSignUpViewController : UIViewController<UITextFieldDelegate>
#property (strong, nonatomic) IBOutlet UIBarButtonItem *barButtonItem;
#property (strong, nonatomic) IBOutlet UITextField *usernameField;
#property (strong, nonatomic) IBOutlet UITextField *passwordField;
#property (strong, nonatomic) IBOutlet UITextField *repeatPasswordField;
- (IBAction)doneEvent:(id)sender;
- (IBAction)cancelEvent:(id)sender;
#end
NewUserSignUpViewController.m
#import "NewUserSignUpViewController.h"
#import "ProfileViewController.h"
#import <Parse/Parse.h>
#import "ActivityView.h"
#interface NewUserSignUpViewController ()
-(void)processFieldEntries;
- (void)textInputChanged:(NSNotification *)note;
- (BOOL)shouldEnableDoneButton;
#end
#implementation NewUserSignUpViewController
#synthesize barButtonItem = _doneButtonInTheBar;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(textInputChanged:) name:UITextFieldTextDidChangeNotification object:_usernameField];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(textInputChanged:) name:UITextFieldTextDidChangeNotification object:_passwordField];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(textInputChanged:) name:UITextFieldTextDidChangeNotification object:_repeatPasswordField];
}
-(void)viewDidAppear:(BOOL)animated
{
[_usernameField becomeFirstResponder];
[super viewDidAppear:animated];
//perform the segue
if (_doneButtonInTheBar.enabled == YES) {
[self performSegueWithIdentifier:#"segueToProfileView" sender:self];
}
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)dealloc {
}
#pragma mark - UITextFieldDelegate
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{ textField.delegate = self;
if (textField == _usernameField) {[_usernameField becomeFirstResponder];}
if (textField == _passwordField){[_passwordField becomeFirstResponder];}
if (textField == _repeatPasswordField)
{
[_repeatPasswordField becomeFirstResponder];
[self processFieldEntries];
}
return YES;
}
-(BOOL)shouldEnableDoneButton
{
BOOL enableDoneButton = NO;
if (_usernameField.text != nil && _usernameField.text.length != 0 &&_passwordField.text != nil &&
_passwordField.text.length !=0 && _repeatPasswordField.text != nil &&
_repeatPasswordField.text.length != 0) {
enableDoneButton = YES;
[self processFieldEntries];
}
return enableDoneButton;
}
-(void)textInputChanged:(NSNotification *)note
{
_doneButtonInTheBar.enabled = [ self shouldEnableDoneButton];
}
- (IBAction)doneEvent:(id)sender {
[_usernameField resignFirstResponder];
[_passwordField resignFirstResponder];
[_repeatPasswordField resignFirstResponder];
NSLog(#"processfieldentries");
[self processFieldEntries];
}
- (IBAction)cancelEvent:(id)sender {
[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)processFieldEntries
{
// Check that we have a non-zero username and passwords.
// Compare password and passwordAgain for equality
// Throw up a dialog that tells them what they did wrong if they did it wrong.
NSString *username = _usernameField.text;
NSString *password = _passwordField.text;
NSString *passwordAgain = _repeatPasswordField.text;
NSString *errorText = #"Please ";
NSString *usernameBlankText = #"enter a username";
NSString *passwordBlankText = #"enter a password";
NSString *joinText = #", and ";
NSString *passwordMismatchText = #"enter the same password twice";
BOOL textError = NO;
// Messaging nil will return 0, so these checks implicitly check for nil text.
if (username.length == 0 || password.length == 0 || passwordAgain.length == 0) {
textError = YES;
//setting the keyboard for th first missing output
if (passwordAgain.length == 0) {
[_repeatPasswordField becomeFirstResponder];
}
if (password.length == 0) {
[_passwordField becomeFirstResponder];
}
if (username.length == 0) {
[_usernameField becomeFirstResponder];
}
if (username.length == 0) {
errorText = [errorText stringByAppendingString:usernameBlankText];
}
if (password.length == 0 || passwordAgain.length == 0) {
if (username.length == 0) { // We need some joining text in the error:
errorText = [errorText stringByAppendingString:joinText];
}
errorText = [errorText stringByAppendingString:passwordBlankText];
}
}else if ([password compare:passwordAgain] != NSOrderedSame)
{errorText = [errorText stringByAppendingString:passwordMismatchText];
[_passwordField becomeFirstResponder];}
if (textError) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:errorText message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:#"Ok", nil];
[alertView show];
return;
// Everything looks good; try to log in.
// Disable the done button for now.
_doneButtonInTheBar.enabled = NO;
ActivityView *activityView = [[ActivityView alloc]initWithFrame:CGRectMake(0.f, 0.f, self.view.frame.size.width, self.view.frame.size.height)];
UILabel *label = activityView.label;
label.text = #"signing up";
label.font = [UIFont boldSystemFontOfSize:20.0f];
[activityView.activityIndicator startAnimating];
[activityView layoutSubviews];
[self.view addSubview:activityView];
// Call into an object somewhere that has code for setting up a user.
// The app delegate cares about this, but so do a lot of other objects.
// For now, do this inline.
NSLog(#"does it reach here");
PFUser *user = [PFUser user];
user.username = username;
user.password = password;
[user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[[error userInfo] objectForKey:#"error"] message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:#"Ok", nil];
[alertView show];
_doneButtonInTheBar.enabled = [self shouldEnableDoneButton];
[activityView.activityIndicator stopAnimating];
[activityView removeFromSuperview];
// Bring the keyboard back up, because they'll probably need to change something.
[_usernameField becomeFirstResponder];
return;
}
// Success!
[activityView.activityIndicator stopAnimating];
[activityView removeFromSuperview];
}];
}
}
#end
You could try not to use performSegueWithIdentifier inside viewDidAppear (performSegue actually take you to the other ViewController). Instead you could call it from an IBAction method connected to the done button, after calling in the same method processFieldEntries. I hope this can help you :)

NSDictionay display

im not able to display the values from this code .plz provide a code to display the mutabledictionay and a
- (void)viewDidLoad{
[super viewDidLoad];
mdict =[[NSMutableDictionary alloc]init];
[mdict setValue:#"abc" forKey:#"def"];
[mdict release];
}
-(void)display{
CFShow(mdict);
}
What about using
-(void)display{
NSLog(#"%#",mdict);
}
Change your method as:
- (void)viewDidLoad{
[super viewDidLoad];
mdict =[[NSMutableDictionary alloc]init];
[mdict setValue:#"abc" forKey:#"def"];
//if you want to display use following statement
[self display];
// [mdict release];//you should not release it here.
}
NOTE: In viewDidLoad you are using [mdict release]; mdict will be released!!!
this should not be in viewDidLoad, put that statement in dealloc.
First You need to create NSMutableDictionary is Public (declare in .h file) because you use it in outside and release its instance in dealloc method
- (void)viewDidLoad{
[super viewDidLoad];
self.mdict =[[NSMutableDictionary alloc]init];
[self.mdict setValue:#"abc" forKey:#"def"];
[self display];
}
-(void)display
{
NSLog(#"%#",[self.mdict objectForKey:#"def"]);
}
and release instance of dictionary in -(void)dealloc method

Resources