Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSPlaceholderDictionary: attempt to insert nil object from objects[1]

I have two UITextField boxes, one for minPrice, and one for maxPrice. When I attempt to run the function triggered by the submitButton IBAction, using those two textfield contents as parameters, it states that the objects are empty with the following error:

'*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[1]'

I can't seem to figure out why the text that is input into these fields isn't saved properly. Am I forgetting something when I programmatically initialize them?

CriteriaViewController.h:

#import <UIKit/UIKit.h>
#import <Parse/Parse.h>
#import "SearchViewController.h"

@interface CriteriaViewController : UIViewController{

IBOutlet UISegmentedControl *Segment;
}


//@property (nonatomic) IBOutlet UITextField *itemSearch;
@property (weak, nonatomic) IBOutlet UITextField *minPrice;
@property (weak, nonatomic) IBOutlet UITextField *maxPrice;
@property (nonatomic, copy) NSNumber *chosenCategory;
@property (nonatomic, copy) NSString *chosenCategoryName;
@property (weak, nonatomic) NSString *itemCondition;
@property (weak, nonatomic) NSString *itemLocation;
@property (weak, nonatomic) NSString *itemSearch;

@end

CriteriaViewController.m:

#import "CriteriaViewController.h"

@interface CriteriaViewController ()
@property (weak, nonatomic) IBOutlet UISegmentedControl *itemConditionSegment;
@property (weak, nonatomic) IBOutlet UISegmentedControl *itemLocationSegment;


@end

@implementation CriteriaViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{

    [super viewDidLoad];

    [self addMinTextField];
    [self addMaxTextField];


    // Condition UISegment
    UISegmentedControl *conditionSegmentedControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:@"Only New", @"Any", nil]];
    conditionSegmentedControl.frame = CGRectMake(87, 190, 157, 30);
    conditionSegmentedControl.selectedSegmentIndex = 0;
    conditionSegmentedControl.tintColor = [UIColor blackColor];
    [conditionSegmentedControl addTarget:self action:@selector(ConditionSegmentControlAction:) forControlEvents: UIControlEventValueChanged];
    [self.view addSubview:conditionSegmentedControl];


    // Location UISegment
    UISegmentedControl *locationSegmentedControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:@"Fast Shipping", @"Large Selection", nil]];
    locationSegmentedControl.frame = CGRectMake(67, 275, 200, 30);
    locationSegmentedControl.selectedSegmentIndex = 0;
    locationSegmentedControl.tintColor = [UIColor blackColor];
    [locationSegmentedControl addTarget:self action:@selector(LocationSegmentControlAction:) forControlEvents: UIControlEventValueChanged];
    [self.view addSubview:locationSegmentedControl];




    // Submit button
    UIButton *submitButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; // Create Round Rect Type button.
    submitButton.frame = CGRectMake(100, 100, 100, 100); // define position and width and height for the button.
    [submitButton setTitle:@"Submit" forState:UIControlStateNormal];

    [submitButton addTarget:self action:@selector(submitButton:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:submitButton];



}



-(void)addMinTextField{
    // This allocates a label
    UILabel *prefixLabel = [[UILabel alloc]initWithFrame:CGRectZero];
    // This sets the font for the label
    [prefixLabel setFont:[UIFont boldSystemFontOfSize:14]];
    // This fits the frame to size of the text
    [prefixLabel sizeToFit];

    // This allocates the textfield and sets its frame
    UITextField *minPrice = [[UITextField  alloc] initWithFrame:
                             CGRectMake(70, 105, 75, 30)];

    // This sets the border style of the text field
    minPrice.borderStyle = UITextBorderStyleRoundedRect;
    minPrice.contentVerticalAlignment =
    UIControlContentVerticalAlignmentCenter;
    [minPrice setFont:[UIFont boldSystemFontOfSize:12]];

    //Placeholder text
    minPrice.placeholder = @"150";

    //Prefix label is set as left view and the text starts after that
    minPrice.leftView = prefixLabel;

    //It set when the left prefixLabel to be displayed
    minPrice.leftViewMode = UITextFieldViewModeAlways;

    // Adds the textField to the view.
    [self.view addSubview:minPrice];

    // sets the delegate to the current class
    minPrice.delegate = self;
}

-(void)addMaxTextField{
    // This allocates a label
    UILabel *prefixLabel = [[UILabel alloc]initWithFrame:CGRectZero];
    // This sets the font for the label
    [prefixLabel setFont:[UIFont boldSystemFontOfSize:14]];
    // This fits the frame to size of the text
    [prefixLabel sizeToFit];

    UITextField *maxPrice = [[UITextField  alloc] initWithFrame:
                             CGRectMake(185, 105, 75, 30)];

    //for max price
    maxPrice.borderStyle = UITextBorderStyleRoundedRect;
    maxPrice.contentVerticalAlignment =
    UIControlContentVerticalAlignmentCenter;
    [maxPrice setFont:[UIFont boldSystemFontOfSize:12]];

    //Placeholder text is displayed when no text is typed
    maxPrice.placeholder = @"300";

    //Prefix label is set as left view and the text starts after that
    maxPrice.leftView = prefixLabel;

    //It set when the left prefixLabel to be displayed
    maxPrice.leftViewMode = UITextFieldViewModeAlways;

    // Adds the textField to the view.
    [self.view addSubview:maxPrice];

    // sets the delegate to the current class
    maxPrice.delegate = self;
}



- (void)ConditionSegmentControlAction:(UISegmentedControl *)segment
{
    if(segment.selectedSegmentIndex == 0)
    {
        // set condition to new
        self.itemCondition = @"new";
    }
    else if (segment.selectedSegmentIndex == 1)
    {
        // set condition to all
        self.itemCondition = @"all";
    }
}

- (void)LocationSegmentControlAction:(UISegmentedControl *)segment
{
    if(segment.selectedSegmentIndex == 0)
    {
        // set location to us
        self.itemLocation = @"US";
    }
    else if (segment.selectedSegmentIndex == 1)
    {
        // set clocation to worldwide
        self.itemLocation = @"Worldwide";
    }
}


- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}






//add all the info to users respective new category object
- (IBAction)submitButton:(id)sender
{
    //if (self.minPriceField.text.length > 0 && self.maxPrice.text.length > 0) {

        [PFCloud callFunctionInBackground:@"userCategorySave"
                           withParameters:@{@"categoryId": self.chosenCategory,
                                              @"minPrice": self.minPrice,
                                            @"maxPrice": self.maxPrice,
                                       @"itemCondition": self.itemCondition,
                                        @"itemLocation": self.itemLocation,
                                        @"categoryName": self.chosenCategoryName,
                                            }
                                         block:^(NSString *result, NSError *error) {

                                             if (!error) {
                                                 NSLog(@"Criteria successfully saved.");

                                                     [self performSegueWithIdentifier:@"SearchCategoryChooserToMatchCenterSegue" sender:self];

                                             }
                                         }];

    //}

}


- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {



//    [PFCloud callFunctionInBackground:@"addToMatchCenter"
//                       withParameters:@{
//                                        @"searchTerm": self.itemSearch,
//                                        @"categoryId": self.chosenCategory,
//                                        @"minPrice": self.minPrice,
//                                        @"maxPrice": self.maxPrice,
//                                        @"itemCondition": self.itemCondition,
//                                        @"itemLocation": self.itemLocation,
//                                        }
//                                block:^(NSString *result, NSError *error) {
//                                    
//                                    if (!error) {
//                                        NSLog(@"'%@'", result);
//                                    }
//                                }];

    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.

}

@end
like image 832
Ghobs Avatar asked Jul 06 '14 23:07

Ghobs


1 Answers

You are creating a NSDictionary using the shorthand @{ key, value} with one or more nil value.

As a preventive technique at the development stage, may I suggest checking all your value(s) using:

NSParameterAssert(self.itemSearch);
NSParameterAssert(self.chosenCategory);
// etc.

This will throw an assert and let you know that your NSDictionary construction is bound to fail.

Now for causes (in your code)... As stated in the comments, you are locally overriding the scope of your class members with local variables:

// This allocates the textfield and sets its frame
UITextField *minPrice = ...

Consider using this construction (if not, of course, creating the UI objects with IB, which you appear to do)

self.minPrice = ({
    UITextField *minPrice = [[UITextField alloc] init...];
    // more initialization of minPrice...

    minPrice;
});
[self.view addSubview:self.minPrice];
like image 134
SwiftArchitect Avatar answered Sep 18 '22 12:09

SwiftArchitect