issue regarding property of class shows null - iphone

i am making game in which i am not using navigation controller but hiding and unhiding different controllers now my problem is as below
This Is going to be view long description you can understand what i am talking about
my flowConverViewController is like this
#import <UIKit/UIKit.h>
#import "FlowCoverView.h"
#import "NewGameController.h"
#import "MenuController.h"
#class NewGameController;
#interface FlowCoverViewController : UIViewController <FlowCoverViewDelegate>
{
}
#property (nonatomic, strong) NewGameController *game;
- (IBAction)done:(id)sender;
#end
flowcontroller.m is like below
when user click on image then image get selected and game should get start
for that delegate method get called which is below
- (void)flowCover:(FlowCoverView *)view didSelect:(int)image
{
NSLog(#"Selected Index %d",image);
UIImage *newimage = [self flowCover:view cover:image];
[
NSLog(#"%#",[self.game menu]); // this shows null
NSLog(#"%#",self.game); // this shows null thats why my below methods which are in another class is not getting called
[self.game menu] playMenuSound];
// game is object of newGameController that we created in .h file and in
same way in newgamecontroller there is object properly of menu class and
playMenuSound is method in menu class
[self.game imagePickedFromPuzzleLibrary:newimage];
[self.game startNewGame];
}
only problem is this methods are not getting called as it shows null i know that i can alloc init them but i cant do that previous data will get lost i have alloc init this properties in previous classes
.
newgamecontroller.h
#property (nonatomic, assign) MenuController *menu;
newgamecontroller.m
{
FlowCoverViewController *c = [[FlowCoverViewController alloc] init];
c.game = self;
NSArray *array = [[NSBundle mainBundle] loadNibNamed:#"TestFC" owner:self options:nil];
c = [array objectAtIndex:0];
[self presentModalViewController:c animated:YES];
}

I'm sorry, you do:
FlowCoverViewController *c = [[FlowCoverViewController alloc] init];
c.game = self;
and then you assign to c a different object with:
NSArray *array = [[NSBundle mainBundle] loadNibNamed:#"TestFC" owner:self options:nil];
c = [array objectAtIndex:0];
[self presentModalViewController:c animated:YES];
How could c still have the property c.game set properly??
EDIT: Try instead
NSArray *array = [[NSBundle mainBundle] loadNibNamed:#"TestFC" owner:self options:nil];
FlowCoverViewController *c = [array objectAtIndex:0];
[self presentViewController:c animated:YES completion:nil]
and let me know.

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"];
}

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

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?

accessing class file crashes when scrolling starts (UIScrollview)

hopefully someone will be able to help me. I have a UIScrollView on my page. The .h file has set the UIscrollviewdelegate.
I have a class file called "Picture.h / Picture.m".
- (id)initWithName:(NSString *)aName filename:(NSString *)aFilename {
self.name = aName;
self.filename = aFilename;
return self;
}
In this class file, I simply set a couple of strings. I load an array with object of this picture class, for example
Picture *image2 = [[Picture alloc] initWithName:#"Apple" filename:#"apple.png"];
[pictureArray addObject: image2];
[image2 release];
Within my viewController, I call this class and assign is as such
Picture *thisPicture = (Picture *)[appDelegate.pictureArray objectAtIndex:0];
view2image.image = [UIImage imageNamed:[NSString stringWithFormat:#"%#", thisPicture.filename]];
The above works fine. The image is set to what ever I put, example, "apple.png". However, when I tried to set this in the - (void) scrollViewDidScroll:(UIScrollView *) method within my viewController, I get a bad exec error and the app crashes.
Yet, if I had an array of filenames (so not storing my class object in the array) and access objectAtIndex:0 in the scrollViewDidScroll - it works fine.
So, this code is OK
nextImageView.image = [UIImage imageNamed: [NSString stringWithFormat:#"%#", [appDelegate.pictureCardsArray objectAtIndex:0]]];
but this crashes
Picture *image3 = (Picture *)[appDelegate.pictureArray objectAtIndex:0];
nextImageView.image = [UIImage imageNamed:[NSString stringWithFormat:#"%#", image3.filename]];
Interestingly though, if I don't try to access the element of image3 (eg image3.filename) it doesn't crash. This is useless though! Also, if I disable the delegate = self for the uiscrollview, then this code works, but none of the scrolling actions are fired. I came across this post (http://stackoverflow.com/questions/1734720/uiscrollview-on-a-uiviewcontroller) when searching for the solution, but cannot see where I might be releasing the viewController early. To be safe, nothing is getting released (yet!)
Hopefully someone might be able to shed some light on it!!
[edit]Just adding in the full class files][/edit]
Picture.h
#import <UIKit/UIKit.h>
#interface Picture : NSObject {
NSString *name;
NSString *filename;
}
#property (nonatomic, copy) NSString *name;
#property (nonatomic, copy) NSString *filename;
- (id)initWithName:(NSString *)aName filename:(NSString *)aFilename;
#end
Picture.m
#import "Picture.h"
#implementation Picture
#synthesize name, filename;
- (id)initWithName:(NSString *)aName filename:(NSString *)aFilename {
self.name = aName;
self.filename = aFilename;
return self;
}
#end
Just for completeness... the solution was as Antwen Van Houdt said - I changed copy to retain and it worked fine.
#import <UIKit/UIKit.h>
#interface Picture : NSObject {
NSString *name;
NSString *filename;
}
#property (nonatomic, retain) NSString *name;
#property (nonatomic, retain) NSString *filename;
- (id)initWithName:(NSString *)aName filename:(NSString *)aFilename;
#end

iOS - Opening a PDF via Quicklook without using UIScrollView

I am trying to open a PDF via the QuickLook framework without using UIScrollView...
I believe I'm missing something...
Where I believe I'm going wrong is that I need to use a QLPreviewController and on the QLPreviewController is a dataSource that has to conform to QLPreviewItem. The documentation states that NSURL does conform to QLPriewItem so I'm setting the preview.dataSource to an NSURL which is throwing an error:
[NSURL numberOfPreviewItemsInPreviewController:]: unrecognized selector sent to instance
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSURL numberOfPreviewItemsInPreviewController:]: unrecognized selector sent to instance 0x5b5f200'
Which makes me think that NSURL does not conform.
all the code I think is necessary...
- (BOOL)previewController:(QLPreviewController *)controller shouldOpenURL:(NSURL *)url forPreviewItem:(id <QLPreviewItem>)item {
return YES;
}
- (NSInteger) numberOfPreviewItemsInPreviewController: (QLPreviewController *) controller {
return [documents count];
}
- (id <QLPreviewItem>) previewController: (QLPreviewController *) controller previewItemAtIndex: (NSInteger) index {
return [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:[documents objectAtIndex:index] ofType:nil]];
}
- (void)pushPDF {
QLPreviewController *preview = [[QLPreviewController alloc] init];
preview.dataSource = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"MCIT_Quiz" ofType:#"pdf"]];
//preview.currentPreviewItemIndex = 0;
[self presentModalViewController:preview animated:YES];
[preview release];
}
I ended up just creating another class to hold my values and use as a datasource, a bit quick and dirty but it works.
//
// documentList.h
//
#import <Foundation/Foundation.h>
#import <QuickLook/QuickLook.h>
#interface DocumentList : NSObject <QLPreviewControllerDataSource, QLPreviewControllerDelegate> {
NSArray *documents;
}
#property (nonatomic, retain) NSArray *documents;
-(void)createList;
-(NSInteger) numberOfPreviewItemsInPreviewController: (QLPreviewController *) controller;
- (id <QLPreviewItem>) previewController: (QLPreviewController *) controller previewItemAtIndex: (NSInteger) index;
#end
inserting text to break up the files
//
// documentList.m
//
#import "DocumentList.h"
#implementation DocumentList
#synthesize documents;
-(void) createList {
documents = [[NSArray arrayWithObjects:#"Quiz.pdf", nil] retain];
}
-(NSInteger) numberOfPreviewItemsInPreviewController: (QLPreviewController *) controller {
return [documents count];
}
- (id <QLPreviewItem>) previewController: (QLPreviewController *) controller previewItemAtIndex: (NSInteger) index {
return [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:[documents objectAtIndex:index] ofType:nil]];
}
#end
Well, I don't see where an NSURL conforms to QLPreviewControllerDataSource. I think you want
preview.dataSource = self;
And then your already written routines (numberOfPreviewItemsInPreviewController and previewController) would return the appropriate NSURL (although it's not clear how "documents" gets filled.).

Sample Application for SQLite

Hello friends
I am developing application in which view has one textField & 2 buttons. When user clicks on "Add" then text from textfield should be stored in datatabse. When user clicks on "Display"then data fetched from database should be displayed in textField. The code written is like this
//SettingsApplicationViewController.h
#import "FMDatabase.h"
#interface SettingsApplicationViewController : UIViewController {
FMDatabase *db;
IBOutlet UITextField *urlField;
IBOutlet UIButton *insertButton;
IBOutlet UIButton *displayButton;
}
#property(nonatomic, retain) IBOutlet UITextField *urlField;
#property(nonatomic, retain) IBOutlet UIButton *insertButton;
#property(nonatomic, retain) IBOutlet UIButton *displayButton;
-(void)insertButtonClicked :(id)sender;
-(void)displayButtonClicked:(id)sender;
-(id)initApp;
#end
// SettingsApplicationViewController.m
#import "SettingsApplicationViewController.h"
#import "FMDatabase.h"
#implementation SettingsApplicationViewController
#synthesize urlField;
#synthesize insertButton;
#synthesize displayButton;
-(id)initApp
{
if(![super init])
return nil;
//DB stored in application bundle
NSString *DBName = #"SettingDB.sqlite";
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingString:DBName];
db = [FMDatabase databaseWithPath:path];
[db setLogsErrors:TRUE];
[db setTraceExecution:TRUE];
if(![db open])
{
NSLog(#"Could not open Database");
return 0;
}
else
{
NSLog(#"Database opened successfully");
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self initApp];
}
-(void)insertButtonClicked :(id)sender
{
[db executeUpdate:#"insert into Settings values (?)",urlField.text];
[self resignFirstResponder];
}
-(void)displayButtonClicked:(id)sender
{
NSString *returnResult = [[NSString alloc]init];
FMResultSet *rs = [db executeQuery:#"select url from Settings"];
while ([rs next])
{
returnResult = [rs stringForColumn:#"url"];
[urlField setText:returnResult];
}
}
// SettingDB.sqlite
CREATE TABLE Settings(url text(50));
I created connections in IB & copied libsqlite3.dylib & FMDatabase file. I dont know why " # " is not printed in this post but I have # in my code.
When I compile this code it is showing 1 error as follows
Command /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/gcc-4.2 failed with exit code 1
Please help me friends.
Thanks
This error is usually displayed when you are referring to a file in Xcode and that file not in the mentioned path. (That file will be shown red in the Project Navigator)
Have you assigned Action for those buttons?
If not do as follows,
Instead of -(void)insertButtonClicked :(id)sender; use -(IBAction)insertButtonClicked :(id)sender; and assign them to respective button action.
or else,
In viewdidLoad,
[insertButton addTarget:self action:#selector(insertButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
[displayButton addTarget:self action:#selector(displaytButtonClicked:) forControlEvents:UIControlEventTouchUpInside];