Encode NSMutableArray - objective-c

EDIT: Ok i decided to save the array in the userDefaults... should be easy, right ?
Save:
NSUserDefaults *userDefs = [NSUserDefaults standardUserDefaults];
[userDefs setObject:videoArray forKey:#"dataArray"];
[userDefs synchronize];
Load:
NSUserDefaults *userDefs = [NSUserDefaults standardUserDefaults];
videoArray = [[NSUserDefaults standardUserDefaults] mutableArrayValueForKey:#"dataArray"];
[tableview reloadData];
NSLog(#"%#",videoArray);
Class of the objects which are in the array:
#interface DEVideoModel : NSObject
#property (copy) NSString *name;
#property (copy) NSImage *thumbnail;
#property (copy) NSDictionary *qualities;
#property (readwrite) float videoSize;
#property (readwrite) float progress;
#property (copy) NSString *filePath;
#property (copy) NSDate *datum;
#end
#synthesize name,filePath,videoSize,qualities,thumbnail,datum,progress;
-(id)init {
self = [super init];
if(self) {
qualities = [[NSDictionary alloc]init];
thumbnail = [[NSImage alloc]init];
}
return self;
}
#end
And my videoArray is (null) when i load it ?! I don't get it. videoArray is a NSMutableArray not NSArray by the way.

IN your code you are writting NSData to NSCoder, so you need to read NSData then convert it to Array.
NSURL *appSupportDir = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:&error];
NSString *path = [NSString stringWithFormat:#"%#/DEConvert.dat",[appSupportDir path]];
NSLog(#"%#",appSupportDir);
NSData *data = [NSData dataWithContentsOfFile:path];
NSMutableArray *arr = [NSKeyedUnarchiver unarchiveObjectWithData:data];
to store object in NSUserDefault
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:arr];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:#"your key"];
Unarchiving is just as easy:
NSData *NewData = [[NSUserDefaults standardUserDefaults] objectForKey:#"your key"];
NSArray *arr = [NSKeyedUnarchiver unarchiveObjectWithData:NewData];

Related

AVAudioPlayer playing multiple songs simultaneously?

I am calling this ViewController from another UITableViewController which pass the the song name and index.For the very first time it play the song but when i go back to the tableView and click another song it play both songs simultaneously.
In .h file I used AVAudioPlayer
#property (nonatomic, strong) AVAudioPlayer *audioPlayer;
In .m file:
- (void)viewDidLoad
{
[super viewDidLoad];
[self sliderValueChanged:volumeSlider];
[self updateTime];
[self playOrPauseSound:nil];
volumeSlider.value=0.5;
count=songArray.count;
[self setupAVPlayerForURL:songIndex];
_audioPlayer.delegate=self;
}
-(void) setupAVPlayerForURL: (int) url {
NSString *songname=[NSString stringWithFormat:#"%#",songArray[songIndex]];
songTitle.text=songname;
NSString* saveFileName = songname;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:saveFileName];
NSURL *url1 = [[NSURL alloc] initFileURLWithPath: path];
self.audioPlayer=[[AVAudioPlayer alloc] initWithContentsOfURL:url1 error:NULL];
[self.audioPlayer play];
self.seekBarSlider.minimumValue = 0.0f;
self.seekBarSlider.maximumValue = self.audioPlayer.duration;
[self updateTime];
self.isPlaying=YES;
_audioPlayer.delegate=self;
[_audioPlayer addObserver:self forKeyPath:#"status" options:0 context:nil];
}
Maybe you have to check if the audioplayer is already playing before lauch another song
if(self.audioplayer && [self.audioplayer isPlaying]){
[self.audioplayer stop];
}

How to get all records From CoreData Base using NSManagedObjectSubClass?

I am trying to implement CoreData in ios Application,Now I want to Fetch all records from Entity MUSTHAFA
My NSManagedObjectedSubClass is MUSTAHFA
MUSTHAFA.m
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#interface MUSTHAFA : NSManagedObject {
#private
}
#property (nonatomic, retain) NSString * FirstName;
#property (nonatomic, retain) NSNumber * Age;
#property (nonatomic, retain) NSString * Location;
#property (nonatomic, retain) NSString * LastName;
#end
#import "MUSTHAFA.h"
#implementation MUSTHAFA
#dynamic FirstName;
#dynamic Age;
#dynamic Location;
#dynamic LastName;
#end
Adding Records to Core Data
-(void)AddRecordToCoreData{
//NSLog(#"______ ADD Core Data Implementaion");
MUSTHAFA *event = (MUSTHAFA *)[NSEntityDescription insertNewObjectForEntityForName:#"MUSTHAFA" inManagedObjectContext:managedObjectContext];
[event setLastName:#"JOHN"];
[event setFirstName:#"JOSE "];
[event setLocation:#"IDUKKI "];
[event setAge:[NSNumber numberWithInt:25]];
NSError *error;
if (![managedObjectContext save:&error])
{
NSLog(#"Error..%#",error);
}
else
{
NSLog(#"Data added to MUSTHAFA ");
}
}
Retrieving all Values from Core Data just like select * from dbTable;
-(void)FetchRecordFromCoreData:(id)data1{
//NSLog(#"______ Fetch Core Data Implementaion");
MUSTHAFA *event = (MUSTHAFA *)[NSEntityDescription insertNewObjectForEntityForName:#"MUSTHAFA" inManagedObjectContext:managedObjectContext];
//USING event how can fetch all record from Data base;
}
USING event (Instance of MUSTAHFA) how can fetch all record from Data base?
NSManagedObjectContext *context = //Get it from AppDelegate
NSFetchRequest *request = [[NSFetchRequest alloc]initWithEntityName:#"MUSTHAFA"];
NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];
if (error != nil) {
//Deal with failure
}
else {
//Deal with success
}
[request release];
AppDelegate *delegate = [UIApplication sharedApplication].delegate;
NSManagedObjectContext *context =[delegate managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc]initWithEntityName:#"Channels"];
NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];
ChannelDBArray=[[NSMutableArray alloc]init];
for (NSManagedObject *obj in results) {
NSArray *keys = [[[obj entity] attributesByName] allKeys];
NSDictionary *dictionary = [obj dictionaryWithValuesForKeys:keys];
}
if (error != nil) {
//Deal with failure
}
else {
//Deal with success
}

How to Add Multiple Placemarks and Annotations to Map

I have a class that loads a map, get my current location, then does a search on my database for companies in an area based on a zip code radius. I am doing a for loop to loop through each address, forward geocode, now I want to put a placemark and annotation for each location. How can I accomplish this. Here is my code:
- (void)locationUpdate:(CLLocation *)location {
locationLabel.text = [location description];
NSNumber *lat = [[NSString alloc] initWithFormat:#"%g", location.coordinate.latitude];
float latValue = [lat floatValue];
NSNumber *lng = [[NSString alloc] initWithFormat:#"%g", location.coordinate.longitude];
float lngValue = [lng floatValue];
mapView=[[MKMapView alloc] initWithFrame:self.view.bounds];
mapView.showsUserLocation=TRUE;
mapView.mapType=MKMapTypeStandard;
mapView.delegate=self;
/*Region and Zoom*/
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta=0.2;
span.longitudeDelta=0.2;
CLLocationCoordinate2D location1=mapView.userLocation.coordinate;
location1.latitude=latValue;
location1.longitude=lngValue;
region.span=span;
region.center=location1;
/*Geocoder Stuff*/
geoCoder=[[MKReverseGeocoder alloc] initWithCoordinate:location1];
geoCoder.delegate=self;
[geoCoder start];
[mapView setRegion:region animated:TRUE];
[mapView regionThatFits:region];
[self.view insertSubview:mapView atIndex:0];
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geoCoder didFindPlacemark:(MKPlacemark *)placemark
{
NSDictionary *zipDic = [placemark addressDictionary];
NSString *zipCode = [zipDic objectForKey:#"ZIP"];
NSString *post = [NSString stringWithFormat:#"zip=%#", zipCode];
NSString *hostString = #"https://www.mysite.com/searchzip.php?";
// Append string and add percent escapes
hostString = [[hostString stringByAppendingString:post] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *hostURL = [NSURL URLWithString:hostString];
NSString *jsonString = [[NSString alloc] initWithContentsOfURL:hostURL];
self.zipArray = [jsonString JSONValue];
NSLog(#"%#", zipArray);
for (NSString *sZip in zipArray) {
NSString *lblAddress = [sZip objectForKey:#"address"];
NSString *hostStr = [[#"http://maps.google.com/maps/geo?q=" stringByAppendingString:lblAddress]stringByAppendingString:#"&key=ABQIAAAA1KqXKe5yJPkX6ii6Ud K-0RSIvIZDM4KnjydqrehqKK56hFf_fxQc0uyCKoh-4i77-5B0Qfc8Gs223Q&sensor=false&output=json"];
hostStr = [hostStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *hostURL = [NSURL URLWithString:hostStr];
NSString *jsonString = [[NSString alloc] initWithContentsOfURL:hostURL];
SBJSON *parser = [[SBJSON alloc] init];
// parse the JSON string into an object - assuming json_string is a NSString of JSON data
NSArray *object = [parser objectWithString:jsonString error:nil];
NSArray *placemarks = [object objectForKey:#"Placemark"];
NSDictionary *mark = [placemarks objectAtIndex:0];
NSDictionary *point = [mark objectForKey:#"Point"];
NSArray *coordinates = [point objectForKey:#"coordinates"];
NSNumber *lat = (NSNumber*)[coordinates objectAtIndex:0];
float latValue = [lat floatValue];
NSNumber *lon = (NSNumber*)[coordinates objectAtIndex:1];
float lonValue = [lon floatValue];
//Here is where I would put placemarks and annotations
}
}
- (void)locationError:(NSError *)error {
locationLabel.text = [error description];
}
#end
I tried...
CLLocationCoordinate2D location = {latitude: latValue, longitude: lonValue};
return location;
But obviously its wrong.
I tried creating a seperate MapAnnotation class to handle the annotations like so:
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#import "AgencyViewController.h"
#interface MapAnnotation : NSObject<MKAnnotation> {
CLLocationCoordinate2D coordinate;
NSString *subtitletext;
NSString *titletext;
}
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
#property (readwrite, retain) NSString *titletext;
#property (readwrite, retain) NSString *subtitletext;
-(id)initWithCoordinate:(CLLocationCoordinate2D) coordinate;
- (NSString *)subtitle;
- (NSString *)title;
-(void)setTitle:(NSString*)strTitle;
-(void)setSubTitle:(NSString*)strSubTitle;
and implement it like so:
CLLocationCoordinate2D newCoord = {latitude: latValue, longitude: lonValue};
MapAnnotation *addAnnotation = [[MapAnnotation alloc] initWithCoordinate:newCoord];
[addAnnotation setTitle:#"The Pin Title"];
[addAnnotation setSubTitle:#"The pin subtitle goes here"];
[mapView addAnnotation:addAnnotation];
And that didnt work either...
Figured it out, needed to add
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
MKPinAnnotationView *pinView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:#"Prospects"];
if(pinView == nil) {
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"Prospects"];
pinView.pinColor = MKPinAnnotationColorGreen;
pinView.animatesDrop = NO;
pinView.canShowCallout = YES;
} else {
pinView.annotation = annotation;
}
return pinView;
}
Now I need to figure out how to change the color of my location pin.

Singleton, NSMutableDictionary and plist

I have a singleton called SettingsManager in my app that should take care of reading/writing settings to a plist. Singleton is synthesized using macro from Cocoa With Love (zipped macro file). I have only changed retain's return type to (oneway void) from (void). This is due to new compiler in iOS that can take care of memory management. My problem is that whenever i call savePrefs, button calling the selector "hangs" on active state, and sometimes I am getting EXC_BAD_ACCESS. So I guess I failed with memory management. Surprisingly, when no plist file is available (right after app installation), all the defaults are correctly stored and retrieved from my NSMutableDictionary. Below is my code. Will be super grateful for your help.
Martin
CODE:
1/ Singleton header
#import <Foundation/Foundation.h>
#define SALARY_PREF_KEY #"MonthlySalary"
#define DEFAULT_SALARY [NSNumber numberWithDouble: 0.0]
#define CURRENCY_PREF_KEY #"Currency"
#define DEFAULT_CURRENCY #"USD"
#define EXPENSES_PREF_KEY #"Expenses"
#define DEFAULT_EXPENSES [NSNumber numberWithDouble: 0.0]
#define TIME_INTERVAL_PREF_KEY #"TimeInterval"
#define DEFAULT_INTERVAL [NSNumber numberWithInteger: 2]
#define SAVINGS_PREF_KEY #"Savings"
#define DEFAULT_SAVINGS [NSNumber numberWithDouble: 0.0]
#interface SettingsManager : NSObject {
NSString *prefsFilePath;
NSMutableDictionary *settingsDictionary;
NSNumber *salary;
NSString *currency;
NSNumber *expenses;
NSNumber *timeInterval;
NSNumber *savings;
}
+ (SettingsManager *)sharedSettingsManager;
#property (nonatomic, retain) NSString *prefsFilePath;
#property (nonatomic, retain) NSMutableDictionary *settingsDictionary;
#property (nonatomic, retain) NSNumber *salary;
#property (nonatomic, retain) NSString *currency;
#property (nonatomic, retain) NSNumber *expenses;
#property (nonatomic, retain) NSNumber *timeInterval;
#property (nonatomic, retain) NSNumber *savings;
- (void) savePrefs;
#end
2/ Implementation:
#import "SynthesizeSingleton.h"
#import "SettingsManager.h"
#implementation SettingsManager
SYNTHESIZE_SINGLETON_FOR_CLASS(SettingsManager);
#synthesize settingsDictionary,
salary,
currency,
expenses,
timeInterval,
savings,
prefsFilePath;
- (id)init {
self = [super init];
if (self) {
if (prefsFilePath == nil) {
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex: 0];
prefsFilePath = [documentsDirectory stringByAppendingPathComponent:#"iEarn.plist"];
}
if ([[NSFileManager defaultManager] fileExistsAtPath: prefsFilePath]) {
settingsDictionary = [[NSMutableDictionary alloc]
initWithContentsOfFile: prefsFilePath];
}
else {
settingsDictionary = [[NSMutableDictionary alloc] initWithCapacity: 7];
[settingsDictionary setObject: DEFAULT_SALARY forKey: SALARY_PREF_KEY];
[settingsDictionary setObject: DEFAULT_CURRENCY forKey: CURRENCY_PREF_KEY];
[settingsDictionary setObject: DEFAULT_EXPENSES forKey: EXPENSES_PREF_KEY];
[settingsDictionary setObject: DEFAULT_INTERVAL forKey: TIME_INTERVAL_PREF_KEY];
[settingsDictionary setObject: DEFAULT_SAVINGS forKey: SAVINGS_PREF_KEY];
[settingsDictionary writeToFile: prefsFilePath atomically: YES];
}
self.salary = [settingsDictionary objectForKey:SALARY_PREF_KEY];
self.currency = [settingsDictionary objectForKey:CURRENCY_PREF_KEY];
self.expenses = [settingsDictionary objectForKey:EXPENSES_PREF_KEY];
self.timeInterval = [settingsDictionary objectForKey:TIME_INTERVAL_PREF_KEY];
self.savings = [settingsDictionary objectForKey:SAVINGS_PREF_KEY];
}
return self;
}
- (void) savePrefs {
[settingsDictionary setObject: salary forKey: SALARY_PREF_KEY];
[settingsDictionary setObject: currency forKey: CURRENCY_PREF_KEY];
[settingsDictionary setObject: expenses forKey: EXPENSES_PREF_KEY];
[settingsDictionary setObject: timeInterval forKey: TIME_INTERVAL_PREF_KEY];
[settingsDictionary setObject: savings forKey: SAVINGS_PREF_KEY];
[settingsDictionary writeToFile: prefsFilePath atomically: YES];
}
- (void) dealloc {
[settingsDictionary dealloc];
[super dealloc];
}
#end
3/ How I call savePrefs
- (IBAction)saveButtonPressed:(id)sender {
[[SettingsManager sharedSettingsManager] setSalary: [NSNumber numberWithDouble: [salary.text doubleValue]]];
[[SettingsManager sharedSettingsManager] setCurrency: currency.text];
[[SettingsManager sharedSettingsManager] setExpenses: [NSNumber numberWithDouble: [expenses.text doubleValue]]];
[[SettingsManager sharedSettingsManager] setTimeInterval: [NSNumber numberWithInt: [intervalStepper value]]];
[[SettingsManager sharedSettingsManager] setSavings: [NSNumber numberWithDouble: [savings.text doubleValue]]];
[[SettingsManager sharedSettingsManager] savePrefs];
}
It seems that you access directly the prefsFilePath instance variable instead of using its accessor:
prefsFilePath = [documentsDirectory stringByAppendingPathComponent:#"iEarn.plist"];
The value stored is auto-released, so after the current pool is drained, the reference is no longer valid. Instead, you should use:
self.prefsFilePath = [documentsDirectory stringByAppendingPathComponent:#"iEarn.plist"];
or
prefsFilePath = [[documentsDirectory stringByAppendingPathComponent:#"iEarn.plist"] retain];
Note: You may either prefix all the property accesses to avoid problems, or rename the instance variables.

Memory Leak from NSMutableArray and NSDictionary

I have a memomry leak problem, maybe somebody can help me.
I try to load an NSMutable array for a pList and show some elements in a TablevView
In the h.File I declare
#interface Bestellung : UIViewController <UITableViewDelegate, UITableViewDelegate> {
NSMutableArray *bestellteVorspeisen;
NSMutableArray *bestellteVorspeisenPreis;
NSMutableArray *bestellteVorspeisenDetails;
NSMutableArray *bestellteVorspeisenBild;
NSMutableArray *bestellteVorspeisenNummer;
NSMutableArray *bestellListe;
IBOutlet UITableView *myTable;
}
#property (nonatomic, retain) NSMutableArray *bestellListe;
#property (nonatomic,retain) NSMutableArray *bestellteVorspeisen;
#property (nonatomic,retain) NSMutableArray *bestellteVorspeisenPreis;
#property (nonatomic,retain) NSMutableArray *bestellteVorspeisenDetails;
#property (nonatomic,retain) NSMutableArray *bestellteVorspeisenBild;
#property (nonatomic,retain) NSMutableArray *bestellteVorspeisenNummer;
#end
In the M.File viewDidLoad I load the pList in bestellListe
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"Bestellung.plist"];
success = [fileManager fileExistsAtPath:filePath];
if (!success)
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"Bestellung" ofType:#"plist"];
success = [fileManager copyItemAtPath:path toPath:filePath error:&error];
}
self.bestellListe = [[NSMutableArray alloc] initWithContentsOfFile:filePath];
Then I generate the MutableArray
bestellteVorspeisen = [[NSMutableArray alloc] initWithCapacity:1];
bestellteVorspeisenPreis = [[NSMutableArray alloc] initWithCapacity:1];
bestellteVorspeisenDetails = [[NSMutableArray alloc] initWithCapacity:1];
bestellteVorspeisenBild = [[NSMutableArray alloc] initWithCapacity:1];
bestellteVorspeisenNummer = [[NSMutableArray alloc] initWithCapacity:1];
Afterwards I fill them from bestellListe
for (NSDictionary *bestellDict in bestellListe)
{ if ([[bestellDict objectForKey:#"Tisch"] isEqualToString:
[NSString stringWithFormat:#"%i",TischNummer]])
{if ([[bestellDict objectForKey: kBestellungKategorieString] isEqualToString: #"Vorspeise"])
[bestellteVorspeisen addObject: [bestellDict objectForKey:kBestellungNameString]];
[bestellteVorspeisenPreis addObject: [bestellDict objectForKey:kBestellungPreisString]];
[bestellteVorspeisenDetails addObject: [bestellDict objectForKey:kBestellungDetailString]];
[bestellteVorspeisenBild addObject: [bestellDict objectForKey:kBestellungBildString]];
[bestellteVorspeisenNummer addObject: [bestellDict objectForKey:kBestellungNummer]];
} // if
} // if
} // for
This causes memoryleaks at
self.bestellListe = [[NSMutableArray alloc] initWithContentsOfFile:filePath];
and
bestellteVorspeisen = [[NSMutableArray alloc] initWithCapacity:1];
bestellteVorspeisenPreis = [[NSMutableArray alloc] initWithCapacity:1];
bestellteVorspeisenDetails = [[NSMutableArray alloc] initWithCapacity:1];
bestellteVorspeisenBild = [[NSMutableArray alloc] initWithCapacity:1];
bestellteVorspeisenNummer = [[NSMutableArray alloc] initWithCapacity:1];
Here ist dealloc
- (void)dealloc {
NSLog(#"Bestellung dealloziert");
[bestellteVorspeisen release];
[bestellteVorspeisenPreis release];
[bestellteVorspeisenDetails release];
[bestellteVorspeisenBild release];
[bestellteVorspeisenNummer release];
[bestellListe release];
[myTable release];
[super dealloc];
Can somebody give me some help, I'm really new in that.
your property synthesized method automatically retains received objects :
#property (nonatomic, retain) NSMutableArray *bestellListe;
So when you do :
self.bestellListe = [[NSMutableArray alloc] initWithContentsOfFile:filePath];
Your bestellListe has a retain count of 2 (the alloc + the retain from the property).
On your dealloc you only release it once :
[bestellListe release];
The simpler solution seems to retain it only once when creating it, with an autoreleased initializer like :
self.bestellListe = [NSMutableArray arrayWithContentsOfFile:filePath];
Hope this can help