Getting error class is not key value coding-compliant for the key name - iphone

I am implementing SearchBar in my TableView. But it will display error when i try to enter text in SearchBar.
This is my NSObject class code .h file :
#import <Foundation/Foundation.h>
#interface ChannelList : NSObject
{
NSString *channelLink;
NSString *channelName;
NSString *channelType;
NSString *channelLogo;
}
#property (nonatomic, copy) NSString *channelName;
#property (nonatomic, copy) NSString *channelType;
#property (nonatomic, copy) NSString *channelLogo;
#property (nonatomic, copy) NSString *channelLink;
+ (id)channelLink:(NSString*)channelLink channelName:(NSString*)achannelName channelType:(NSString*)achannelType channelLogo:(NSString*)achannelLogo;
#end
And .m file :
#import "ChannelList.h"
#implementation ChannelList
#synthesize channelLogo,channelName,channelType,channelLink;
+ (id)channelLink:(NSString*)channelLink channelName:(NSString*)achannelName channelType:(NSString*)achannelType channelLogo:(NSString*)achannelLogo{
ChannelList *ChannelList = [[self alloc] init];
[ChannelList setChannelLink:channelLink];
[ChannelList setChannelName:achannelName];
[ChannelList setChannelType:achannelType];
[ChannelList setChannelLogo:achannelLogo];
return ChannelList;
}
#end
Using this array to populate my table view
channelAllData = [NSArray arrayWithObjects:
[ChannelList channelLink:#"http://cdn.m.yuppcdn.net/liveorigin/smil:ndtvhindi_iphone.smil/playlist.m3u8" channelName:#"NDTV" channelType:#"NEWS" channelLogo:#"ndtv.png"],[ChannelList channelLink:#"http://cdn.m.yuppcdn.net/liveorigin/smil:aajtak_iphone.smil/playlist.m3u8" channelName:#"Aaj_Tak" channelType:#"NEWS" channelLogo:#"Aaj_Tak"],[ChannelList channelLink:#"http://cdn.m.yupptv.tv/liveorigin/smil:indiatv.smil/playlist.m3u8" channelName:#"India_tv" channelType:#"NEWS" channelLogo:#"India_tv_logo.gif"],[ChannelList channelLink:#"http://cdn.m.yuppcdn.net/liveorigin/smil:headlinetoday_iphone.smil/playlist.m3u8" channelName:#"HeadlinesToday" channelType:#"NEWS" channelLogo:#"HeadlinesToday.png"],nil];
searchedData = [NSMutableArray arrayWithCapacity:[channelAllData count]];
Here searchedData is the search result of my SearchBar.
And here I'm populating my searchedData, and getting error as I mentioned in title.
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
// remove all data that belongs to previous search
[searchedData removeAllObjects];
if([searchText isEqualToString:#""]||searchText==nil){
[self.tableView reloadData];
return;
}
[self filterContentForSearchText:searchText];
// NSLog(#"%i",searchedData.count);
[self.tableView reloadData];
}
- (void)filterContentForSearchText:(NSString*)asearchText
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.name contains[c] %#",asearchText];
NSLog(#"predicate %#",predicate);
NSArray *tempArray = [channelAllData filteredArrayUsingPredicate:predicate];
searchedData = [NSMutableArray arrayWithArray:tempArray];
}

In the predicate, you're using self.name whereas there's no name property declared on your class. Did you mean self.channelName instead?

Related

writing data using NSKeyedArchiver

I trying to learn how to save array of objects using NSKeyedArchiver and I coded a small application to do that and I logged to see if the array was saved but everytime I get 0 for array count and here is the code.
ViewController.h
#interface ViewController : UIViewController
{
IBOutlet UITextField *text;
IBOutlet UITextField *textName;
IBOutlet UITextField *textAge;
IBOutlet UILabel *name;
IBOutlet UILabel *age;
BOOL flag;
BOOL choice;
NSString *documentDirectory;
NSMutableArray *anArray;
Person *p;
NSData *data;
}
-(BOOL) dataFilePath;
-(IBAction)readPlist;
-(IBAction) writePlist;
#property (strong,nonatomic)IBOutlet UITextField *text;
#property (strong,nonatomic)IBOutlet UITextField *textName;
#property (strong,nonatomic)IBOutlet UITextField *textAge;
#property (strong,nonatomic)IBOutlet UILabel *name;
#property (strong,nonatomic)IBOutlet UILabel *age;
#property (strong,nonatomic)NSString *documentDirectory;
#property (strong,nonatomic)NSMutableArray *anArray;
#end
ViewController.m
#interface ViewController ()
#end
#implementation ViewController
#synthesize text,documentDirectory,textAge,textName,name,age,anArray;
- (void)viewDidLoad
{
[super viewDidLoad];
// checking if the file was created and show a message if its created or not.
if ([self dataFilePath]) {
NSLog(#"File Created !");
} else {
NSLog(#"File Not Created !");
}
NSLog(#"File location : %#",documentDirectory);
choice = YES;
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(BOOL) dataFilePath
{
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentDirectory = [path objectAtIndex:0];
documentDirectory = [documentDirectory stringByAppendingPathComponent:#"MilmersĀ­Data.dat"];
return TRUE;
}
- (IBAction)writePlist
{
p.name = textName.text;
p.age = [textAge.text intValue];
[anArray addObject:p];
for (int i=0; i<[anArray count]+1; i++) {
Person *pp = [[Person alloc]init];
pp=[anArray objectAtIndex:i];
NSLog(#"Name: %#",pp.name); // checking the names in pp object but getting null
}
data = [NSKeyedArchiver archivedDataWithRootObject:anArray];
[data writeToFile:documentDirectory options:NSDataWritingAtomic error:nil];
NSLog(#"Array length: %d",[anArray count]); //Always got array count zero.
}
-(IBAction)readPlist
{
NSString *filePath = documentDirectory;
NSMutableArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
NSLog(#"The array is: %#",array); // it shows that there is nothing in the array
}
#end
I wrote the class for writing .plist files originally but I knew later that I cant store objects in .plist file so I tried so that with archive, thats why the method name have plist in it.
Thank you in advance
Looks like you aren't ever creating an instance of p to add to the array. Try:
Person *p = [[Person alloc] init];
p.name = textName.text;
p.age = [textAge.text intValue];
[anArray addObject:p];
your index limit was also wrong in this loop
for (int i=0; i<[anArray count]; i++) {
NSLog(#"Name: %#", [[anArray objectAtIndex:i] name]);
}
you should really have been seeing a couple of different crashes...
Try adding this in viewDidLoad
[[NSFileManager defaultManager] createFileAtPath:documentDirectory contents:nil error:nil];
It looks like you never do this, and using archives to write to files only works if the file already exists (make sure you only do this once, otherwise every time that view is loaded the file will be emptied of all the data in it). And when you do this
if ([self dataFilePath])
It's pointless, because no matter what it always returns yes, whether the file exists or not.
Does your Person class implement NSCoding?
Specifically you need to implement something like the following in Person.m:
- (id)initWithCoder:(NSCoder *)decoder {
self = [super init];
if (!self) {
return nil;
}
self.name = [decoder decodeObjectForKey:#"name"];
self.age = [decoder decodeObjectForKey:#"age"];
return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:self.name forKey:#"name"];
[encoder encodeObject:self.age forKey:#"age"];
}

Json serialize array in objective-c

I want to serialize array to JSON.
Here is my JSON -
{
"User":{"Id":"1222","Email":"asdad#adasd.com"},
"Person":{"Name":"John","Surname":"Smith"}
}
values 1222, asdad#adasd.com, John, Smith are examples. this values will be define in controller.
I don't know how to handle serialize this arrays inside JSON.
I need to send objects - user and person to the server with different values, depending on the user. This is my model. Both are arrays.
Here is my code
Header
#import <Foundation/Foundation.h>
#import "BaseRequest.h"
#interface SaveUserProfileRequest : BaseRequest {
NSMutableArray *_user;
NSMutableArray *_person;
NSMutableArray *_address;
NSString *_userId;
NSString *_userEmail;
NSString *_userName;
NSString *_userSurname;
}
- (id)initWithUser:(NSMutableArray*)user andPerson:(NSMutableArray*)person andAddress:(NSMutableArray*)address andUserId:(NSString*)userId andUserEmail:(NSString*)userEmail andUserName:(NSString*)userName andUserSurname:(NSString*)userSurname;
#property (nonatomic, strong) NSMutableArray* user;
#property (nonatomic, strong) NSMutableArray* person;
#property (nonatomic, strong) NSMutableArray* address;
#property (nonatomic, strong) NSString* userId;
#property (nonatomic, strong) NSString* userEmail;
#property (nonatomic, strong) NSString* userName;
#property (nonatomic, strong) NSString* userSurname;
#end
Implementation
#import "SaveUserProfileRequest.h"
#import "SaveUserProfileResponse.h"
#import "OrderedDictionary.h"
#import "BaseData.h"
#implementation SaveUserProfileRequest
#synthesize user=_user, person=_person, address=_address, userId=_userId, userEmail=_userEmail, userName=_userName, userSurname=_userSurname;
- (id)initWithUser:(NSMutableArray*)user andPerson:(NSMutableArray*)person andAddress:(NSMutableArray*)address andUserId:(NSString*)userId andUserEmail:(NSString*)userEmail andUserName:(NSString*)userName andUserSurname:(NSString*)userSurname; {
self = [super init];
if(self){
self.user = user;
self.person = person;
self.address = address;
self.userId = userId;
self.userEmail = userEmail;
self.userName = userName;
self.userSurname = userSurname;
}
return self;
}
- (NSDictionary*) serialize{
OrderedDictionary *sup = [OrderedDictionary dictionaryWithCapacity:3];
[sup setValue:self.user forKey:#"User"];
[sup setValue:self.person forKey:#"Person"];
NSArray *users = [OrderedDictionary valueForKey:#"User"];
_user = [NSMutableArray arrayWithCapacity:[users count]];
for(NSDictionary *user in users){
OrderedDictionary *userDict = [OrderedDictionary dictionaryWithCapacity:2];
[userDict setValue:self.userId forKey:#"Id"];
[userDict setValue:self.userEmail forKey:#"Mail"];
return userDict;
}
NSArray *persons = [OrderedDictionary valueForKey:#"Person"];
_person = [NSMutableArray arrayWithCapacity:[persons count]];
for(NSDictionary *person in persons){
OrderedDictionary *personsDict = [OrderedDictionary dictionaryWithCapacity:2];
[personsDict setValue:self.userName forKey:#"Name"];
[personsDict setValue:self.userSurname forKey:#"Surname"];
return personsDict;
}
return sup;
}
Please, help me a little
Every little hint will be really appreciate.
Thanks !
For handeling JSON in Objective-C, I always use JSONKit. You can fork it here: https://github.com/johnezang/JSONKit
Some examples on how it can be used:
NSArray *array = #[..];
NSString *arrayAsJsonString = [array JSONString];
NSString *string = #"..";
id objectFromJsonString = [string objectFromJSONString]; // i.e an NSArray or NSDictionary
If your app is for iOS 5 or greater, you can use NSJSONSerialization:
http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSJSONSerialization_Class/Reference/Reference.html
Otherwise I recommend SBJson.

Memory management of container classes

I've made a container class to store a single tweet. Its initialized by passing in a dictionary object which is a single tweet.
I then store an array of these 'tweets' which I process through to display in a table.
The project is now finished and I am reviewing everything at the moment and I was wondering is there a better way to do this in the future. Is the memory handled correctly. I declare the string member vars with 'copy' and later in the dealloc I use a 'release' rather than just setting them to 'nil'.
Is my init ok or could that be improved?
Tweet.h
#import
#interface Tweet : NSObject
{
NSString * _userName;
NSString * _tweetText;
NSString * _tweetURL;
}
#property (nonatomic, copy) NSString * userName;
#property (nonatomic, copy) NSString * tweetText;
#property (nonatomic, copy) NSString * tweetURL;
- (id) initWithDict:(NSDictionary *)productsDictionary;
#end
Tweet.m
#implementation Tweet
#synthesize userName = _userName;
#synthesize tweetText = _tweetText;
#synthesize tweetURL = _tweetURL;
- (id) initWithDict:(NSDictionary *)productsDictionary
{
NSDictionary *aDict = [productsDictionary objectForKey:#"user"];
self.userName = [aDict objectForKey:#"screen_name"];
self.tweetText = [productsDictionary objectForKey:#"text"];
NSRange match;
match = [self.tweetText rangeOfString: #"http://"];
if (match.location != NSNotFound)
{
NSString *substring = [self.tweetText substringFromIndex:match.location];
NSRange match2 = [substring rangeOfString: #" "];
if (match2.location == NSNotFound)
{
self.tweetURL = substring;
}
else
{
self.tweetURL = [substring substringToIndex:match2.location];
}
}
else
{
self.tweetURL = nil;
}
return self;
}
-(void) dealloc
{
[self.tweetText release];
[self.tweetURL release];
[self.userName release];
[super dealloc];
}
#end
Many Thanks,
Code
At first sight, I see no inherent flaws here. That looks fine. I would prefer to do:
-(void) dealloc
{
[_tweetText release];
[_tweetURL release];
[_userName release];
[super dealloc];
}
But what you do is good as well.

return a static const []

So in my model I have the following code... I am successfully able to return each individual value. I want to know how am I able to return the entire speakerTable []... Maybe some advice. Thanks!
typedef struct {
NSUInteger speakerID;
NSString * speakerName;
NSString * speakerPosition;
NSString * speakerCompany;
} SpeakerEntry;
static const SpeakerEntry speakerTable [] =
{
{0, #"name", #"position", #"company"},
{1, #"name", #"position", #"company"},
{-1, nil, nil, nil}
};
This works correctly...
-(NSString *) stringSpeakerCompanyForId:(NSUInteger) identifier{
NSString * returnString = nil;
if ([self helpCount] > identifier) {
returnString = speakerTable[identifier].speakerCompany;
}
return returnString;
}
This does not work at all..
-(id) getSpeaker{
//if ([speakerTable[0].speakerName isKindOfClass:[NSString class]])
// NSLog(#"YES");
NSArray * myArray3 = [NSArray arrayWithArray:speakerTable];
return myArray3;
}
arrayWithArray expects an NSArray, not a C array.
The first one works because you are using it like a C array.
Alternatively - don't use a struct, use an object instead:
Create a class called Speaker.
In Speaker.h
#interface Speaker : NSObject {}
#property (nonatomic, assign) NSUinteger id;
#property (nonatomic, copy) NSString name;
#property (nonatomic, copy) NSString position;
#property (nonatomic, copy) NSString company;
- (void)initWithId:(NSUInteger)anId name:(NSString *)aName position:(NSString *)aPosition company:(NSString *)aCompany;
#end
in Speaker.m
#import "Speaker.h"
#implementation Speaker
#synthesize id, name, position, company;
- (void)initWithId:(NSUInteger)anId name:(NSString *)aName position:(NSString *)aPosition company:(NSString *)aCompany {
if (!([super init])) {
return nil;
}
id = anId;
NSString name = [[NSString alloc] initWithString:aName];
NSString position = [[NSString alloc] initWithString:aPosition];
NSString company = [[NSString alloc] initWithString:aCompany];
return self;
}
- (void)dealloc {
[name release];
[position release];
[company release];
[super dealloc];
}
#end
And now in your calling code you can create an immutable array of speakers with:
Speaker *speaker0 = [[Speaker alloc] initWithId:0 name:#"name0" position:#"position0" company:#"company0"];
Speaker *speaker1 = [[Speaker alloc] initWithId:1 name:#"name1" position:#"position1" company:#"company1"];
Speaker *speakerNull = [[Speaker alloc] initWithId:-1 name:nil position:nil company:nil];
NSArray *speakerArray [[NSArray arrayWithObjects: speaker0, speaker1, speakerNull] retain]
[speaker0 release];
[speaker1 release];
[speakerNull release];
note: this is typed straight in, so feel free to mention/correct typos or errors
The method arrayWithArray takes in an NSArray as an argument, not a C array.

trying to set a delegate method to get urlConnection data

I've been going around and around, I've been trying to use this example but running into trouble in the delegate method. I'm trying to figure out how to close this out. Looks like I've got a lot set correctly but need help on final step:
I'm getting a -[ThirdTab apiFinished:]: unrecognized selector sent to instance.
On line two of the WebServiceAPI.m : the self.aDelegate =aDelegate is giving me an error:
2) Local declaration of aDelegate hides instance variable.
This is my first go around with using delegates like this an can't figure out this error.
Thanks.
This is in my ThirdTab UITableViewController:
-(void)viewDidLoad {
[super viewDidLoad];
WebServiceAPI *api = [[WebServiceAPI alloc] init];;
api.delegate =self;
[api DataRequest:data3 delegate:self];
// this is where I'm trying to connect data3 to my tableview.
self.tableDataSource3 = [data3 objectForKey:#"Rows"];
self.webApi = api;
[api release];
This is the WebServiceAPI.h:
#import <UIKit/UIKit.h>
#class WebServiceAPI;
#protocol WebServiceAPIDelegate;
#interface WebServiceAPI : NSObject
{
id<WebServiceAPIDelegate>aDelegate;
NSDictionary *data3;
NSArray *rowsArrayFamily;
NSMutableData *receivedData;
NSString *jsonreturnFF;
}
#property (nonatomic, assign) id<WebServiceAPIDelegate>aDelegate;
#property (nonatomic, retain) NSDictionary *data3;
#property (retain,nonatomic) NSArray *rowsArrayFamily;
#property (nonatomic, retain) NSMutableData *receivedData;
#property (nonatomic, retain) NSString *jsonreturnFF;
- (void) DataRequest: (id) aDelegate;
#end
#protocol WebServiceAPIDelegate
#required
-(void)apiFinished:(WebServiceAPI*)api;
-(void)api:(WebServiceAPI*)api failedWithError:(NSError*)error;
#end
Here is the WebServiceAPI.m where I'm having the issue:
- (void) DataRequest:data3 delegate:(id) aDelegate; {
self.aDelegate = aDelegate;
NSUserDefaults *defaultsF = [NSUserDefaults standardUserDefaults];
NSString *useridFF = [defaultsF objectForKey:kUseridKey];
NSString *urlstrF = [[NSString alloc] initWithFormat:#"http://www.~.php?userid=%#",useridFF];
NSURLRequest *req3 =[NSURLRequest requestWithURL:[NSURL URLWithString:urlstrF]];
NSURLConnection *conn3 = [[NSURLConnection alloc] initWithRequest:req3 delegate:self];
NSMutableData *data =[[NSMutableData alloc] init];
self.receivedData = data;
// self.connection = conn3;
}
Your WebService.h declares a property:
#property (nonatomic, assign) id<WebServiceAPIDelegate>aDelegate;
Your WebService.m uses a different property:
self.delegate = aDelegate;
You can either change the name of the property to delegate in WebService.h, or use the current name of the property in WebService.m.