I need to update position in core data base. When I add object or remove it from that base everything works fine. Problem occurs when I want to update object in that base. The problem is that program throws me:
Thread 1: EXC_BAD_ACCES(code = 2, adres = 0x38).
It's weird because it throws this error but updtades object at core data. I'm using simulator on Xcode 5. I've tried to comment line by line back in code but it hasn't helped anymore. Taking look at the address of the error and the screen shot there is no address compatible with each other. What is wrong?
Code is this:
[self insertPositionRightAfterChangeValues:name rating:[changedRate stringValue] urlMain:[newInsert urlMain] contentUrl:[newInsert contentUrl] coverUrl:[newInsert coverUrl] date:[newInsert date] type:[newInsert type] int:integer];
And the rest of this method:
-(void)insertPositionRightAfterChangeValues:(NSString *)name rating:(NSString *)rating urlMain:(NSString *)urlMain contentUrl:(NSString *)contentUrl coverUrl:(NSString *)coverUrl date:(NSString *)date type:(NSString *)type int:(int)position
{
int motherPosision = position;
//insert new one
NSManagedObjectContext *context2 = [self managedObjectContext];
Kwejki * newEntry = [NSEntityDescription insertNewObjectForEntityForName:#"Kwejki" inManagedObjectContext:context2];
newEntry.name = [[NSString alloc] initWithString: name];
newEntry.rating = [[NSString alloc] initWithString: rating];
newEntry.urlMain = [[NSString alloc] initWithString: urlMain];
newEntry.contentUrl = [[NSString alloc] initWithString: contentUrl];
newEntry.coverUrl = [[NSString alloc] initWithString: coverUrl];
newEntry.date = [[NSString alloc] initWithString: date];
newEntry.type = [[NSString alloc] initWithString: type];
NSLog(#"%#", newEntry.name);
NSLog(#"%#", newEntry.rating);
NSLog(#"%#", newEntry.urlMain);
NSLog(#"%#", newEntry.contentUrl);
NSLog(#"%#", newEntry.coverUrl);
NSLog(#"%#", newEntry.date);
NSLog(#"%#", newEntry.type);
NSError *error2;
if (![context2 save:&error2]) {
NSLog(#"Whoops, couldn't save: %#", [error2 localizedDescription]);
}
else{
NSLog(#"SAVED!!!");
}
}
And the screenshot with this error:
UPDATE:
When I comment line where I invoke method to insert new object I get following error: CoreData: error: Failed to call designated initializer on NSManagedObject class 'Kwejki'
UPDATE 2:
#interface Kwejki : NSManagedObject<NSCopying>
#property (nonatomic, strong) NSString * type;
#property (nonatomic, strong) NSString * contentUrl;
#property (nonatomic, strong) NSString * coverUrl;
#property (nonatomic, strong) NSString * rating;
#property (nonatomic, strong) NSString * urlMain;
#property (nonatomic, strong) NSString * date;
#property (nonatomic, strong) NSString * name;
#end
#implementation Kwejki
#synthesize name;
#synthesize date;
#synthesize urlMain;
#synthesize rating;
#synthesize coverUrl;
#synthesize contentUrl;
#synthesize type;
-(Kwejki *)copyWithZone:(NSZone *)zone
{
Kwejki *copyModel = [[Kwejki allocWithZone:zone] init];
if(copyModel)
{
copyModel.name = [self name];
copyModel.date = [self date];
copyModel.urlMain = [self urlMain];
copyModel.rating = [self rating];
copyModel.coverUrl = [self coverUrl];
copyModel.contentUrl = [self contentUrl];
copyModel.type = [self type];
}
return copyModel;
}
#end
-(void)addNewPosition:(ScrollViewViewController *)ScrollController recentlyDownloadedItem:(KwejkModel *)modelTmp
{
if(modelTmp == nil)
{
NSLog(#"YES NULL");
}
else
{
NSLog(#"Not null");
}
Kwejki * newEntry = [NSEntityDescription insertNewObjectForEntityForName:#"Kwejki" inManagedObjectContext:self.managedObjectContext];
NSLog(#"%#", [modelTmp getNameOfItem]);
newEntry.name = [[NSString alloc] initWithString:[modelTmp getNameOfItem]];
newEntry.rating = [modelTmp getRateOfPosition];
newEntry.urlMain = [modelTmp getUrlAdress];
newEntry.contentUrl = [modelTmp getContentUrl];
newEntry.coverUrl = [modelTmp getCoverImage];
newEntry.date = [modelTmp getDateOfItem];
if([modelTmp getType] == photo)
{
newEntry.type = #"0";
}
else if([modelTmp getType] == gif)
{
newEntry.type = #"1";
}
else if ([modelTmp getType] == video)
{
newEntry.type = #"2";
}
NSLog(#"%#", newEntry.name);
NSLog(#"%#", newEntry.rating);
NSLog(#"%#", newEntry.urlMain);
NSLog(#"%#", newEntry.contentUrl);
NSLog(#"%#", newEntry.coverUrl);
NSLog(#"%#", newEntry.date);
NSLog(#"%#", newEntry.type);
NSError *error;
if (![self.managedObjectContext save:&error]) {
NSLog(#"Whoops, couldn't save: %#", [error localizedDescription]);
}
else{
NSLog(#"UDALO SIE!!!");
}
[modelArray insertObject:newEntry atIndex:0];
[self.tableView reloadData];
}
I've tried to overcome this problem just adding new object again as update but it also doesn't helped. How I add new object: I tap long on position, new window opens and there I add new values, invoke from that view method from Main ViewController, and here it crashes. When I add normally object as described above but in separate window everything works. I really don't know what is wrong.
When I see this error it normally mean that I did not setup my NSManageObject correctly.
Things to check:
Add a break point in your insertPositionRightAfterChangeValues method and step through to find where the exception is thrown. (My guess is when your creating your Kwejki object.)
That Kwejki is a subclass of NSManageObject.
That Kwejki entity and class name are correct. (Could you show your .xcdatamodeId entity properties for Kwejki?)
If everything is correct, then for an insanity check I would create the Kwejki object the long way.
NSEntityDescription *entity = [NSEntityDescription entityForName:NSStringFromClass([Kwejki class]) inManagedObjectContext:context2];
Kwejki* newEntry = [[Kwejki alloc] initWithEntity:entity insertIntoManagedObjectContext:context2];
Then you can see if the entity is a problem or your Kwejki is.
P.S. As a helpful suggestion instead of typing in the entity name.
Kwejki * newEntry = [NSEntityDescription insertNewObjectForEntityForName:#"Kwejki" inManagedObjectContext:context2];
I would do something like this.
Kwejki * newEntry = [NSEntityDescription entityForName:NSStringFromClass([Kwejki class]) inManagedObjectContext:context2];
This give you a compiler check for entity name.
Related
So I have a custom TVShow object that has some base fields like id, showName, airDate etc. which are all either NSStrings or NSIntegers and I am attempting to create a bunch of these objects via some data I have gotten from an API online.
So I loop through my NSArray of JSON data and create a TVShow object for each response:
TVShow *show = [[TVShow alloc] initWithData:[NSJSONSerialization JSONObjectWithData:data options:0 error:&error]];
[self.showArray addObject:show];
However, only 7 of these ever get created and then any code below this just ceases to run. I have a NSLog(#"Added"); printing after I create the show and it only gets called 6 times. If I add breakpoints after any of this code, they never get called. I'm not sure what's going on but it must be something to do with how I have set up my TVShow object?
It currently looks like:
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#interface TVShow : NSObject
#property NSInteger showID;
#property NSString *showName;
#property NSString *airDate;
#property double rating;
#property NSString *imageUrl;
#property NSString *showSummary;
#property NSString *episodeSummary;
#property NSInteger season;
#property NSInteger episode;
- (id)initWithData:(NSDictionary *)data;
#end
and the .m file:
#import <UIKit/UIKit.h>
#import "TVShow.h"
#implementation TVShow
- (id)initWithData:(NSDictionary*)data {
self = [super init];
if(self) {
[self buildObjectFromData:data];
}
return self;
}
-(void)buildObjectFromData:(NSDictionary*)data {
NSDictionary *dict = [data objectForKey:#"_embedded"];
NSDictionary *dict2 = [dict objectForKey:#"nextepisode"];
NSDictionary *dict3 = [data objectForKey:#"image"];
NSString *airDate = [dict2 valueForKey:#"airstamp"];
NSInteger season = [[dict2 valueForKey:#"season"] integerValue];
NSInteger episode = [[dict2 valueForKey:#"episode"] integerValue];
NSString *episodeSummary = [dict2 valueForKey:#"summary"];
NSString *showName = [data valueForKey:#"name"];
NSString *showSummary = [data valueForKey:#"summary"];
NSString *imageUrl = [dict3 valueForKey:#"medium"];
NSInteger showID = [[data valueForKey:#"id"] integerValue];
self.airDate = airDate;
self.showName = showName;
self.season = season;
self.episode = episode;
self.showSummary = [self stringByStrippingHTML:showSummary];
self.episodeSummary = [self stringByStrippingHTML:episodeSummary];
self.imageUrl = imageUrl;
self.showID = showID;
}
-(NSString *) stringByStrippingHTML:(NSString*)string {
NSRange r;
NSString *s = string;
while ((r = [s rangeOfString:#"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound)
s = [s stringByReplacingCharactersInRange:r withString:#""];
return s;
}
#end
If I create the object as just: [[TVShow alloc] init]; everything works fine, so it must be something wrong with this model is what I'm thinking. I'm unsure of what to try next, but any help would be greatly appreciated here.
Turns out there were cases that casued:
-(NSString *) stringByStrippingHTML:(NSString*)string {
NSRange r;
NSString *s = string;
while ((r = [s rangeOfString:#"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound)
s = [s stringByReplacingCharactersInRange:r withString:#""];
return s;
}
to go into infinite loops. Removing this snippet fixed the freeze.
MY CODE
.h
#interface fileHandler : NSObject
#property NSMutableArray *arrCategoryList;
#property NSMutableDictionary *dicCategoryList;
#property NSMutableDictionary *dicAllSubCategoryList;
#property NSMutableDictionary *dicProductList;
+(fileHandler *)getDataHandler;
-(void)categoryStorage:(NSMutableArray *)arrCategory :(NSMutableDictionary *)dicCategory :(NSMutableDictionary *)dicSubCategory;
.m
static fileHandler *internalInstance=Nil;
static dispatch_once_t internalOnceToken=0;
#implementation fileHandler
-(id)init
{
self=[super init];
[self allocateMemory];
return self;
}
+(fileHandler *)getDataHandler
{
dispatch_once(&internalOnceToken,^{
internalInstance = [[fileHandler alloc] init];
if(internalInstance) {
NSLog(#"Internal instance created: %#", internalInstance);
}
});
if(internalOnceToken == -1) {
NSLog(#"Internal instance exists: %#", internalInstance);
}
return internalInstance;
}
-(void)allocateMemory
{ NSLog(#"incoming");
self.arrCategoryList=[[NSMutableArray alloc]init];
self.dicCategoryList=[[NSMutableDictionary alloc]init];
self.dicAllSubCategoryList=[[NSMutableDictionary alloc]init];
self.dicProductList=[[NSMutableDictionary alloc]init];
}
-(void)categoryStorage:(NSMutableArray *)arrCategory :(NSMutableDictionary *)dicCategory :(NSMutableDictionary *)dicSubCategory
{
// arrCategory =[[NSMutableArray alloc]init];
self.arrCategoryList=arrCategory;
// [self.arrCategoryList addObject:arrCategory];
// NSLog(#"inside data handler file==%#",self.arrCategoryList);
// dicCategory=[[NSMutableDictionary alloc]init];
self.dicCategoryList=dicCategory;
// dicSubCategory=[[NSMutableDictionary alloc]init];
self.dicAllSubCategoryList=dicSubCategory;
}
Here i have created the static thread and then i am trying to store all the values in to mentioned array and dictionary in other class ,once i have stored the values here then i have to access those data to any where in my app.
Is it Possible?
Is it Right Way?
Another classFile
.m
Like this i am trying to store the values in NSobject Class Array.
for(NSDictionary *DicHoleCategories in ArrCategory)
{
NSMutableDictionary *DicAllValues=[[NSMutableDictionary alloc]init];
[DicAllValues setObject:[[DicHoleCategories objectForKey:#"name"] length] !=0?[DicHoleCategories objectForKey:#"name"] :#"" forKey:#"name"];
StrName=[DicHoleCategories objectForKey:#"image"];
[DicAllValues setObject:[DicHoleCategories objectForKey:#"subcategory"] forKey:#"subcategory"];
if(StrName!=nil)
{
subimages=[NSString stringWithFormat:LocalImage"%#",StrName];
[DicAllValues setObject:subimages forKey:#"image"];
[arrImages addObject:[DicAllValues objectForKey:#"image"]];
}
[ArrName addObject:DicAllValues];
[arrSubCategory addObject:[DicAllValues objectForKey:#"subcategory"]];
[dicSubCategory setObject:[DicAllValues objectForKey:#"subcategory"] forKey:#"subcategory"];
[dicAllValues setObject:dicAllValues forKey:#"hole"];
}
[file categoryStorage:ArrCategory :dicAllValues :dicSubCategory];
OUTPUT:
Collection <__NSArrayM: 0x7f8c33c7b220> was mutated while being enumerated.'
I am facing problems when i tries to save 40,000 records into CoreData Entity.
I am getting 40,000 records by consuming the webservice using AFNetworking, the response is in JSON. Than i divide the data into 4 , 10000 record chunks and then assign these 4 chunks to separate NSOperation objects (i have created subclass of NSOperation) and add these NSOperation Objects to NSOperationQueue.
The problem is that this way it is taking too much time to save the data into CoreData. And i want to find a solution where i can load the data very quickly.
This is the code in which i am creating NSOperation objects and adding them to NSOperationQueue.
- (void)casesResponseReceived:(NSArray*)array
{
id responseObject = [array objectAtIndex:0];
NSManagedObjectContext *moc = [array objectAtIndex:1];
NSString *responseString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSArray *response = [responseString JSONValue];
NSString *responseStr = [response JSONRepresentation];
NSRange range = [responseStr rangeOfString:#"["];
int index = 0;
int objectsCount = 5000;
if (range.location == 0) {
NSInteger count = objectsCount;
totalOperationsCount = 0;
completedOperationsCount = 0;
self.myQueue = [[NSOperationQueue alloc] init];
while (count == objectsCount) {
if ((index+count) > [response count]) {
count = [response count] - index;
}
NSArray *subArray = [response subarrayWithRange:NSMakeRange(index, count)];
index += objectsCount;
CaseParseOperation *operation = [[CaseParseOperation alloc] initWithData:subArray MOC:moc];
operation.delegate = self;
totalOperationsCount++;
[self.myQueue addOperation:operation];
}
/*
if (self.delegate && [self.delegate respondsToSelector:#selector(serviceHelperDidCasesReceivedSuccessful:)]) {
[self.delegate serviceHelperDidCasesReceivedSuccessful:self];
}*/
}
else {
if (self.delegate && [self.delegate respondsToSelector:#selector(serviceHelperDidCasesReceivedFailed:)]) {
[self.delegate serviceHelperDidCasesReceivedFailed:self];
}
}}
CaseOperation.h
#class CaseParseOperation;
#protocol CaseParseOperationProtocol <NSObject>
-(void)caseParseOperationDidOperationComplete: (CaseParseOperation*)caseParseOperation;
#end
#interface CaseParseOperation : NSOperation
#property (nonatomic, weak) id<CaseParseOperationProtocol> delegate;
-(id)initWithData:(NSArray*)parseData MOC:(NSManagedObjectContext*)moc;
#end
CaseOperation.m
#interface CaseParseOperation()
#property (nonatomic, copy) NSArray *casesData;
#property (nonatomic, strong) NSManagedObjectContext *mainMOC;
#property (nonatomic, strong) NSManagedObjectContext *localMOC;
#end
#implementation CaseParseOperation
- (id)initWithData:(NSArray*)parseData MOC:(NSManagedObjectContext*)moc
{
self = [super init];
if (self) {
self.casesData = [parseData copy];
self.mainMOC = moc;
}
return self;
}
- (void)main
{
#autoreleasepool {
self.localMOC = [[NSManagedObjectContext alloc] init];
self.localMOC.persistentStoreCoordinator = self.mainMOC.persistentStoreCoordinator;
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(mergeChanges:)
name: NSManagedObjectContextDidSaveNotification
object: self.localMOC];
[self parseData];
}
}
-(void) mergeChanges: (NSNotification*) saveNotification {
dispatch_async(dispatch_get_main_queue(), ^{
[self.mainMOC mergeChangesFromContextDidSaveNotification:saveNotification];
});
if (self.delegate && [self.delegate respondsToSelector:#selector(caseParseOperationDidOperationComplete:)]) {
[self.delegate caseParseOperationDidOperationComplete:self];
}
}
- (void)parseData
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *ent = [NSEntityDescription entityForName:#"Case" inManagedObjectContext:self.localMOC];
fetchRequest.entity = ent;
NSString *predicateString = [NSString stringWithFormat:#"caseNumber == $caseNumber"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString];
//NSMutableArray *insertedObjects = [[NSMutableArray alloc] init];
for (NSMutableDictionary *dic in self.casesData) {
if (self.isCancelled) {
break;
}
NSString *desc = [dic valueForKey:#"description"];
BOOL enabled = [[dic valueForKey:#"enabled"] boolValue];
NSString *billToCustomerNo = [dic valueForKey:#"billToCustomerNo"];
NSString *caseNo = [dic valueForKey:#"caseNo"];
NSString *billToName = [dic valueForKey:#"billToName"];
NSString *personResponsible = [dic valueForKey:#"personResponsible"];
NSDictionary *variables = #{ #"caseNumber" : caseNo };
fetchRequest.predicate = [predicate predicateWithSubstitutionVariables:variables];
NSArray *matchedObj = [self.localMOC executeFetchRequest:fetchRequest error:nil];
if ([matchedObj count] > 0) {
Case *caseObj = [matchedObj objectAtIndex:0];
caseObj.isEnabled = [NSNumber numberWithBool:enabled];
caseObj.caseDescription = desc;
caseObj.customerNumber = billToCustomerNo;
caseObj.customerName = billToName;
caseObj.personResponsible = personResponsible;
}
else {
/*
Case *caseObj = [[Case alloc] initWithEntity:[NSEntityDescription entityForName:#"Case"
inManagedObjectContext:self.localMOC] insertIntoManagedObjectContext:nil];
caseObj.caseNumber = caseNo;
caseObj.customerName = billToName;
caseObj.customerAddress = #"";
caseObj.customerPhone = #"";
caseObj.caseDescription = desc;
caseObj.customerNumber = billToCustomerNo;
caseObj.isEnabled = [NSNumber numberWithBool:enabled];
caseObj.personResponsible = personResponsible;
[insertedObjects addObject:caseObj];
*/
[Case createObjectWithCaseNumber:caseNo customerName:billToName customerAddress:#"" customerPhone:#"" caseDescription:desc customerNumber:billToCustomerNo isEnabled:enabled personResponsible:personResponsible MOC:self.localMOC];
}
}
/*
if ([insertedObjects count] > 0) {
NSError *error = nil;
BOOL isInserted = [self.localMOC obtainPermanentIDsForObjects:insertedObjects error:&error];
if (error || !isInserted) {
NSLog(#"Error occured");
}
}
*/
if ([self.localMOC hasChanges]) {
[self.localMOC save:nil];
}
}
#end
The first thing to do is run Instruments and find the bottlenecks, as #jrturton recommends.
But there's one huge glaring bottleneck that's apparent from reading the code. To avoid duplicates, you're doing a fetch-- for every incoming instance. With 40k records you'll have to do 40k fetches during the import process, and that's going to be slow no matter what.
You can improve that by processing the data in batches:
Get a bunch of caseNumber values into an array
Do a fetch with a predicate of caseNumber IN %#, with the array as the argument.
Use that array to check for duplicates.
You'll need to experiment a little to see how many "a bunch" is in step 1. Higher numbers mean fewer fetches, which is good for speed. But higher numbers also mean more memory use.
For a more detailed discussion, see Apple's Efficiently Importing Data guide, especially the section named "Implementing Find-or-Create Efficiently".
Thanks guys valuable suggestions. But i have solved that issue by just altering some technique in the parseData function.
-(void)parseData
{
NSString *predicateString = [NSString stringWithFormat:#"caseNumber == $caseNumber"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString];
NSArray *allCases = [Case getAllCaseObjectsWithMOC:self.localMOC];
for (NSMutableDictionary *dic in self.casesData) {
if (self.isCancelled) {
break;
}
NSString *caseNo = [dic valueForKey:#"caseNo"];
NSDictionary *variables = #{ #"caseNumber" : caseNo };
predicate = [predicate predicateWithSubstitutionVariables:variables];
NSArray *matchedObj = [allCases filteredArrayUsingPredicate:predicate];
if ([matchedObj count] == 0) {
NSString *desc = [dic valueForKey:#"description"];
BOOL enabled = [[dic valueForKey:#"enabled"] boolValue];
NSString *billToCustomerNo = [dic valueForKey:#"billToCustomerNo"];
NSString *billToName = [dic valueForKey:#"billToName"];
NSString *personResponsible = [dic valueForKey:#"personResponsible"];
[Case createObjectWithCaseNumber:caseNo customerName:billToName customerAddress:#"" customerPhone:#"" caseDescription:desc customerNumber:billToCustomerNo isEnabled:enabled personResponsible:personResponsible MOC:self.localMOC];
}
}
if ([self.localMOC hasChanges]) {
[self.localMOC save:nil];
}
}
Very new to iOS, a bit lost on what to do. I actually HAVE all that I need, I just need help putting said information into my tableview now. I am debugging and everything is correct when I hover over the variables in my "init" function, but when I go down to the function that handles the cells something is just not clicking. Very frustrating having the information you need but don't know how to put it where you want.
I hate coming to SO for these kind of questions but I have exhausted all other options. Before posting on here, I have tried everything. I tried to google other projects that I can reference, did not find any that was iOS 7 or relevant to my project. I apologize for this elementary question, and thank you in advance.
MasterViewController.m
#interface MasterViewController () {
__block NSString * jsonString;
}
#end
#implementation MasterViewController
#synthesize coursesController = _coursesController;
-(void)getJSONString
{
jsonString = [JSONHelper JSONgetString:#"http://iam.colum.edu/portfolio/api/course?json=True"];
}
-(void)initCourses
{
[_coursesController.masterCoursesList
removeLastObject];
NSError *coursesError = nil;
NSArray *coursesNameList =
[NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding]
options:NSJSONReadingMutableContainers
error: &
coursesError];
if(coursesError)
NSLog(#"[%# %#] JSON error: %#", NSStringFromClass([self class]),
NSStringFromSelector(_cmd), coursesError.localizedDescription);
NSArray *coursesNames = [coursesNameList objectAtIndex:0];
for (NSString *courseName in coursesNameList) {
NSString *stringToUse = [courseName substringFromIndex:8];
//initialize variables
NSString *name = courseName;
NSInteger *courseid = 00;
NSString *imageUrl = nil;
//add current building to list
[_coursesController masterCoursesListWithName:name AndcourseID:courseid AndimageURL:imageUrl];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CoursesCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Courses *courseAtIndex = [self.coursesController objectInListAtIndex:indexPath.row];
[[cell textLabel] setText:courseAtIndex.courseName];
return cell;
}
CoursesDataController.m
#interface CoursesDataController()
-(void)initializeDefaultDataList;
#end
#implementation CoursesDataController
#synthesize masterCoursesList = _masterCoursesList;
-(void)initializeDefaultDataList
{
NSMutableArray *coursesList = [[NSMutableArray alloc] init];
Courses *course = [[Courses
alloc]initWithName:#"Loading Now..." AndcourseID:00];
[coursesList addObject:course];
}
-(void)setMasterCoursesList:(NSMutableArray *)newCourseList
{
if(_masterCoursesList != newCourseList)
{
_masterCoursesList = [newCourseList mutableCopy];
}
} //this function is created when you create a NSMutableArray MasterCoursesList
-(id)init
{
if (self = [super init])
{
[self initializeDefaultDataList];
return self;
}
return nil;
}
-(NSUInteger) countOfList
{
return [self.masterCoursesList count];
}
-(Courses *)objectInListAtIndex:(NSInteger)theIndex
{
return [self.masterCoursesList objectAtIndex:theIndex];
}
-(void)masterCoursesListWithName:(NSString *)cName
AndcourseID:(NSInteger *)cID
AndimageURL:(NSString *)cURL
{
Courses *courses;
courses = [[Courses alloc] initWithName:cName
AndcourseID:cID
AndimageURL:cURL];
[self.masterCoursesList addObject:courses];
}
-(void)courseName:(NSString *)cName
AndcourseID:(NSInteger *)cID
{
Courses *courses;
courses = [[Courses alloc] initWithName:cName AndcourseID:cID];
[self.masterCoursesList addObject:courses];
}
#end
CoursesDataController.h
#import <Foundation/Foundation.h>
#class Courses;
#interface CoursesDataController : NSObject
#property(nonatomic, copy) NSMutableArray *
masterCoursesList;
-(NSUInteger) countOfList;
-(Courses *)objectInListAtIndex:(NSInteger)theIndex;
- (void)masterCoursesListWithName:(NSString *)cName
AndcourseID:(NSInteger *)cID
AndimageURL:(NSString *)cURL;
- (void)courseName:(NSString *)cName
AndcourseID:(NSInteger *)cID;
#end
JSONHelper.m
+(NSString *)JSONgetString:(NSString *)query
{
NSString* searchURL = [NSString stringWithFormat:query];
NSError* error = nil; //error for NSUSRLConnection
NSURLResponse* response = nil;
NSMutableURLRequest* request = [[NSMutableURLRequest alloc] init];
NSURL* URL = [NSURL URLWithString:searchURL];
[request setURL:URL];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setTimeoutInterval:30];
NSData* data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (error)
{
NSLog(#"Error performing request %#", searchURL);
return 0;
}
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"jsonString:%#", jsonString);
return jsonString;
}
I have a lot of code posted, however there are only a few lines that really matter for my question. When I hover over "name" in the following line of code [_coursesController masterCoursesListWithName:name AndcourseID:courseid AndimageURL:imageUrl];
I get what I need (it loops through each JSON array and displays each one). But in the function that handles my cells, when I hover over courseName it doesn't say anything.
Courses *courseAtIndex = [self.coursesController objectInListAtIndex:indexPath.row];
[[cell textLabel] setText:courseAtIndex.courseName];
EDITS:
numberOfRowsInSection function in MasterViewController.m
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.coursesController countOfList];
}
Try this,
in CoursesDataController.m
-(void)initializeDefaultDataList
{
self.masterCoursesList = [[NSMutableArray alloc] init];
Courses *course = [[Courses
alloc]initWithName:#"Loading Now..." AndcourseID:00];
[self.masterCoursesList addObject:course];
}
I'm trying to filter the results of a list of employee contacts that I keep in my app but am getting the following error : 'Can't use in/contains operator with collection LAST (not a collection)'
I've tried several variations with the NSPredicate command, self, self.last, employee.last, last == 'smith' (this one doesn't generate an error but doesn't return any results).
NSMutableArray *employeesList = [[NSMutableArray alloc] init];
Person2 *employee = [[Person2 alloc] init];
employee.first = #"bob";
employee.last = #"black";
[employeesList addObject:employee];
employee = [[Person2 alloc] init];
employee.first = #"jack";
employee.last = #"brown";
[employeesList addObject:employee];
employee = [[Person2 alloc] init];
employee.first = #"george";
employee.last = #"smith";
[employeesList addObject:employee];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"last contains[cd] %#", #"black"];
NSArray *filteredKeys = [employeesList filteredArrayUsingPredicate:predicate];
NSLog(#"filtered : %#",filteredKeys);
[person2.h]
#interface Person2 : NSObject
{
#private
}
#property (nonatomic, retain) NSString *first;
#property (nonatomic, retain) NSString *last;
+ (Person2 *)personWithFirst:(NSString *)first andLast:(NSString *)last;
#end
[person2.m]
#import "Person2.h"
#implementation Person2
#synthesize first, last;
- (id)init {
self = [super init];
if (self) {
}
return self;
}
+ (Person2 *)personWithFirst:(NSString *)first andLast:(NSString *)last {
Person2 *person = [[Person2 alloc] init];
[person setFirst:first];
[person setLast:last];
return person;
}
- (NSString *)description {
return [NSString stringWithFormat:#"%# %#", [self first], [self last]];
}
#end
I've got an NSArray category that does this sort of thing easily:
#interface NSArray (FilterAdditions)
- (NSArray *)filterObjectsUsingBlock:(BOOL (^)(id obj, NSUInteger idx))block;
#end
#implementation NSArray (FilterAdditions)
- (NSArray *)filterObjectsUsingBlock:(BOOL (^)(id, NSUInteger))block {
NSMutableArray *result = [NSMutableArray array];
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (block(obj, idx)) {
[result addObject:obj];
}
}];
return result;
}
So you would call it like this:
NSArray *filteredEmployees =
[employeeList filterObjectsUsingBlock:^BOOL(id obj, NSUInteger idx){
return [(Person2 *)obj.last isEqualToString:#"black"];
}];
So I found the answer and now I feel very dumb!! The use of "first" and "last" are reserved names and cannot be used. I changed the variables to firstName and lastName and it works perfectly.
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html.
Thank you all for your comments and assistance.