What i'm trying to accomplish is something like
Person *person1 = [[Person alloc]initWithDict:dict];
and then in the NSObject "Person", have something like:
-(void)initWithDict:(NSDictionary*)dict{
self.name = [dict objectForKey:#"Name"];
self.age = [dict objectForKey:#"Age"];
return (Person with name and age);
}
which then allows me to keep using the person object with those params. Is this possible, or do I have to do the normal
Person *person1 = [[Person alloc]init];
person1.name = #"Bob";
person1.age = #"123";
?
Your return type is void while it should instancetype.
And you can use both type of code which you want....
Update:
#interface testobj : NSObject
#property (nonatomic,strong) NSDictionary *data;
-(instancetype)initWithDict:(NSDictionary *)dict;
#end
.m
#implementation testobj
#synthesize data;
-(instancetype)initWithDict:(NSDictionary *)dict{
self = [super init];
if(self)
{
self.data = dict;
}
return self;
}
#end
Use it as below:
testobj *tt = [[testobj alloc] initWithDict:#{ #"key": #"value" }];
NSLog(#"%#",tt.ss);
change your code like this
-(id)initWithDict:(NSDictionary*)dict
{
self = [super init];
if(self)
{
self.name = [dict objectForKey:#"Name"];
self.age = [dict objectForKey:#"Age"];
}
return self;
}
So you can use modern objective-c style to get associative array values ;)
-(id)initWithDict:(NSDictionary*)dict
{
self = [super init];
if(self)
{
self.name = dict[#"Name"];
self.age = dict[#"Age"];
}
return self;
}
Related
My Objective-C experience is not good, I would love if someone can help with this.
There are some other code around but I believe I simplified this to just the problem. What I am trying to do is to save a double (packed to NSNumber) with a key, below is my code:
.h
#interface MyClass : something
{
MyMap* usemap;
}
#end
#interface MyMap : something
#property (atomic, strong) NSMutableDictionary* mmap;
#end
.m
#implementation MyMap
#class MyClass;
NSMutableDictionary* mmap = [[NSMutableDictionary alloc] init];
#end
#implementation MyClass
MyMap* usemap = [MyMap alloc];
//-void { switch() { case x:
NSString* key = #"testkey";
NSNumber* value = [NSNumber numberWithDouble:1];
NSLog(#"Saving value: %# to key: %#",value,key);
[usemap.mmap setObject:value forKey:key];
NSNumber* get = [usemap.mmap objectForKey:key];
NSLog(#"Saved value: %# to key: %#",get,key);
Now this prints:
Saving value: 1 to key: testkey
Saved value: (null) to key: testkey
What am I missing? it should have saved the double number '1'.
You need to override MyClass init method and initialize MyMap in it usemap = [[MyMap alloc] init]. Then override MyMap init method and initialize mmap in it self.mmap = [[NSMutableDictionary alloc] init].
Do rest of the work in MyClass overridden init method. Here's a rough sketch:
.h
#interface MyClass : something
{
MyMap* usemap;
}
#end
#interface MyMap : something
#property (atomic, strong) NSMutableDictionary* mmap;
#end
.m
#implementation MyMap
#class MyClass;
- (instancetype)init {
if ((self = [super init]))
self.mmap = [[NSMutableDictionary alloc] init];
return self;
}
#end
#implementation MyClass
- (instancetype)init {
if ((self = [super init]))
{
usemap = [[MyMap alloc] init];
NSString* key = #"testkey";
NSNumber* value = [NSNumber numberWithDouble:1];
NSLog(#"Saving value: %# to key: %#",value,key);
[usemap.mmap setObject:value forKey:key];
NSNumber* get = [usemap.mmap objectForKey:key];
NSLog(#"Saved value: %# to key: %#",get,key);
}
return self;
}
#end
Hope it helps!
Try this:
MyMap.h:
#import <UIKit/UIKit.h>
#interface MyMap : NSObject
#property (atomic, strong) NSMutableDictionary* mmap;
#end
MyMap.m:
#import "MyMap.h"
#interface MyMap ()
#end
#implementation MyMap
#end
ViewController.m:
MyMap *usemap = [[MyMap alloc] init];
usemap.mmap = [[NSMutableDictionary alloc] init];
NSString* key = #"testkey";
NSNumber* value = [NSNumber numberWithDouble:1];
NSLog(#"Saving value: %# to key: %#",value,key);
[usemap.mmap setObject:value forKey:key];
NSNumber* get = [usemap.mmap objectForKey:key];
NSLog(#"Saved value: %# to key: %#",get,key);
The result:
2017-01-21 20:48:59.563 TestOC[4161:50263] Saving value: 1 to key: testkey
2017-01-21 20:48:59.564 TestOC[4161:50263] Saved value: 1 to key: testkey
Setting up the internals of a object is done with an -init method.
#implementation MyMap
#class MyClass;
// NO NO NO! don't even ask what this does
// NSMutableDictionary* mmap = [[NSMutableDictionary alloc] init];
// YES: Use -init to setup the initial state of an object.
- (instancetype)init {
self = [super init];
if (self != nil) {
// NOTE: _mmap is the instance variable for the property self.mmap.
_mmap = [[NSMutableDictionary alloc] init];
}
return self;
}
#end
I used to store the array data downloaded from the server.
But I can not save them in the singleton array.
It seems without access to the object.
Why ulatitude, ulongitude, uaccuracy, uplacename is nil?...
in .h file
#import <Foundation/Foundation.h>
#interface LocationData : NSObject
{
NSMutableArray *ulatitude;
NSMutableArray *ulongitude;
NSMutableArray *uaccuracy;
NSMutableArray *uplacename;
}
#property (nonatomic, retain) NSMutableArray *ulatitude;
#property (nonatomic, retain) NSMutableArray *ulongitude;
#property (nonatomic, retain) NSMutableArray *uaccuracy;
#property (nonatomic, retain) NSMutableArray *uplacename;
+ (LocationData*) sharedStateInstance;
#end
in .m file
#import "LocationData.h"
#implementation LocationData
#synthesize uaccuracy;
#synthesize ulatitude;
#synthesize ulongitude;
+ (LocationData*) sharedStateInstance {
static LocationData *sharedStateInstance;
#synchronized(self) {
if(!sharedStateInstance) {
sharedStateInstance = [[LocationData alloc] init];
}
}
return sharedStateInstance;
}
#end
use
[manager POST:urlStr parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"%#",responseObject);
// json response array
if ([responseObject isKindOfClass:[NSArray class]]) {
NSArray *responseArray = responseObject;
NSDictionary *responseDict = [[NSDictionary alloc] init];
LocationData* sharedState = [LocationData sharedStateInstance];
for(NSUInteger i=0; i < responseArray.count; i++)
{
responseDict = [responseArray objectAtIndex:i];
double dlat = [[responseDict objectForKey:#"lat"] doubleValue];
double dlng = [[responseDict objectForKey:#"lng"] doubleValue];
[[sharedState ulatitude] addObject:[NSString stringWithFormat:#"%f",dlat]];
[[sharedState ulongitude] addObject:[NSString stringWithFormat:#"%f",dlng]];
[[sharedState uaccuracy] addObject:[responseDict objectForKey:#"rad"]];
[[sharedState uplacename] addObject:[responseDict objectForKey:#"place_name"]];
}
You always need to initialize your arrays. You should do somewhere before you try to add something to them:
arrayName = [[NSMutableArray alloc] init];
otherwise you'll always get error because they have not been initialized.
In your case you should override your LocationData init function like this:
- (instancetype)init {
self = [super init];
if (self) {
self.yourArrayName = [[NSMutableArray alloc] init];
// And so on....
}
return self;
}
You need to initialize your object properly. Basically your member variables ("ivars") are pointing to nothing ("nil").
This initializer added to your .m file code do the job.
-(instancetype)init {
if ((self = [super init])) {
self.accuracy = [NSMutableArray array];
self.latitude = [NSMutableArray array];
self.longitude = [NSMutableArray array];
self.uplacename = [NSMutableArray array];
}
return self;
}
As a singleton pattern, I'd prefer the following:
+ (LocationData*) sharedStateInstance {
static LocationData *sharedStateInstance = nil;
static dispatch_once_t onceToken = 0;
dispatch_once(&onceToken, ^{
sharedStateInstance = [[LocationData alloc] init];
});
return sharedStateInstance;
}
Although singletons might not be as bad they are often said to be, I don't thing that this is a good usage for them. Your specific problem has nothing to do with that design choice, though.
Try this code. Write getters for your NSMutableArrays.
#import <Foundation/Foundation.h>
#interface LocationData : NSObject
#property (nonatomic, retain) NSMutableArray *ulatitude;
#property (nonatomic, retain) NSMutableArray *ulongitude;
#property (nonatomic, retain) NSMutableArray *uaccuracy;
#property (nonatomic, retain) NSMutableArray *uplacename;
+ (LocationData*) sharedStateInstance;
#end
#import "LocationData.h"
#implementation LocationData
#synthesize uaccuracy = _uaccuracy;
#synthesize ulatitude = _ulatitude;
#synthesize ulongitude = _ulongitude;
+ (LocationData*) sharedStateInstance {
static LocationData *sharedStateInstance;
#synchronized(self) {
if(!sharedStateInstance) {
sharedStateInstance = [[LocationData alloc] init];
}
}
return sharedStateInstance;
}
-(NSMutableArray*)uaccuracy
{
if(_uaccuracy == nil)
{
_uaccuracy = [[NSMutableArray alloc]init];
}
return uaccuracy;
}
-(NSMutableArray*)ulongitude
{
if(_ulongitude == nil)
{
_ulongitude = [[NSMutableArray alloc]init];
}
return ulongitude;
}
-(NSMutableArray*)ulatitude
{
if(_ulatitude == nil)
{
_ulatitude = [[NSMutableArray alloc]init];
}
return ulatitude;
}
-(NSMutableArray*)uplacename
{
if(_uplacename == nil)
{
_uplacename = [[NSMutableArray alloc]init];
}
return uplacename;
}
#end
you don't allocate/init any array...
you can create them in your singleton creation method
+ (LocationData*) sharedStateInstance {
static LocationData *sharedStateInstance;
#synchronized(self) {
if(!sharedStateInstance) {
sharedStateInstance = [[LocationData alloc] init];
sharedStateInstance.ulatitude = [[NSMutableArray alloc] init];
// (add others...)
}
}
return sharedStateInstance;
}
Replace your LocationData.m file with below code , this will work . As you have to alloc and init the array then only you can add object in array
+ (LocationData*) sharedStateInstance {
static LocationData *sharedStateInstance;
#synchronized(self) {
if(!sharedStateInstance) {
sharedStateInstance = [[LocationData alloc] init];
uaccuracy = [[NSMutableArray alloc]init];
ulatitude = [[NSMutableArray alloc]init];
ulongitude = [[NSMutableArray alloc]init];
uplacename = [[NSMutableArray alloc]init];
}
}
return sharedStateInstance;
}
In creating a login screen with static logins I'm trying to store them privately in the following class implementation. When a button creates IONServer objects I initialize it with the function -(void)login:(NSString *)username password:(NSString *)pw and pass it two UITextField.text strings.
If you notice in the init I am testing stuff with NSLog but at every breakpoint it seems like the storedLogins NSMutable array is nil.
IONServer.m
#import "IONServer.h"
#import "IONLoginResult.h"
#interface IONServer ()
#property (nonatomic) NSMutableArray *storedLogins;
#end
#implementation IONServer
-(void)createStoredLogins
{
NSArray *firstUser = #[#"user1",#"pass1"];
NSArray *secondUser = #[#"user2",#"pass2"];
[self.storedLogins addObject:firstUser];
[self.storedLogins addObject:secondUser];
}
-(instancetype)init {
self = [super init];
if (self) {
[self createStoredLogins];
NSLog(#"Stored logins: %#", _storedLogins);
NSLog(#"Stored user: %#", _storedLogins[0][0]);
}
return self;
}
-(void)login:(NSString *)username password:(NSString *)pw
{
NSArray *logins = [[NSArray alloc]initWithArray:_storedLogins];
for (int i = 0; i < [logins count]; i++) {
if (username == logins[i][0] && pw == logins[i][1]) {
IONLoginResult *result = [[IONLoginResult alloc] initWithResult:YES errorMessage:#"Success!"];
self.result = result;
break;
} else {
IONLoginResult *result = [[IONLoginResult alloc] initWithResult:NO errorMessage:#"Error!"];
self.result = result;
}
}
}
-(void)logout
{
}
#end
You need to initialize the array:
-(instancetype)init {
self = [super init];
if (self) {
_storedLogins = [[NSMutableArray alloc] init];
[self createStoredLogins];
NSLog(#"Stored logins: %#", _storedLogins);
NSLog(#"Stored user: %#", _storedLogins[0][0]);
}
return self;
}
How to Change or Update NSMuttableDictionary i apply code below
in User.h file the code
#interface User : NSObject
#property (nonatomic, strong) NSNumber *userID;
#property (nonatomic, strong) NSString *avatar;
#property (nonatomic, strong) NSString *firstname;
-(User *)initWithDictionary:(NSDictionary *)dictionary;
#end
then in User.m file the code
#import "User.h"
#implementation User
#synthesize userID;
#synthesize avatar;
#synthesize firstname;
-(User *)initWithDictionary:(NSDictionary *)dictionary
{
self = [super init];
if (self)
{
self.userID = [dictionary objectForKey:#"IdUser"];
self.avatar = [dictionary objectForKey:#"Avatar"];
self.firstname = [dictionary objectForKey:#"FirstName"];
}
return self;
}
#end
in my .pch file
#define AppDelegateInstance ((AppDelegate *)[UIApplication sharedApplication].delegate)
then i got the all key and value like this
AppDelegateInstance.loggedUser = [[User alloc] initWithDictionary:[tempArray objectAtIndex:0]];
Response == (
{
IdUser = 1;
Avatar = "Nishant_1.jpg
FirstName = Nishant;
}
)
Now my question is How to update
{
Avatar = "Nishant_1.jpg(Not update **Nishant_1.jpg** to **xyz.jpg**)
FirstName = Nishant(Not Update **Nishant** to **xyz**);
}
If anybody know this plz give me some answer to solve my query
Thanks in Advanced!!!
- (void)updateWithDictionary:(NSDictionary *)dictionary
{
id userId = [dictionary objectForKey:#"IdUser"] ;
if (userId) {
self.userID = userId ;
}
id avatar = [dictionary objectForKey:#"Avatar"] ;
if (avatar) {
self.avatar = avatar ;
}
id firstname = [dictionary objectForKey:#"FirstName"];
if (firstname) {
self.firstname = firstname ;
}
}
Why don't you write a method to update your properties like
-(User *)updateWithDictionary:(NSDictionary *)dictionary
{
if (self)
{
self.userID = [dictionary objectForKey:#"IdUser"];
self.avatar = [dictionary objectForKey:#"Avatar"];
self.firstname = [dictionary objectForKey:#"FirstName"];
}
I am trying to create a NSMutableDictionary in my class. I have read many post in stackoverflow to understand the difference. But now i am totally confused. So any one correct me , which one is the correct way of initialing a NSMutableDictionary in my class . I have to access this dictiionary in many areas of my application .So suggest me the good way of using the variable initialization ...
/// .h file
#interface ActiveFeeds : NSObject {
}
#property (nonatomic, copy) NSMutableDictionary *invDictionary;
#property (nonatomic, retain) NSString *filePath;
#end
#implementation ActiveFeeds
#synthesize filePath;
#synthesize invDictionary;
- (id)init{
self = [super init];
if (self != nil){
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithContentsOfFile:self.filePath];
self.invDictionary = [dictionary mutableCopy];
dictionary release];
}
return self;
}
/* And use self.invDictionary all in the application */
- (void)setObjectAtKey:(NSMutableDictionary *)objectDic atKey:(NSString *)setKey{
[self.invDictionary setObject:objectDic forKey:setKey];
}
- (void)dealloc {
[self.invDictionary release];
[self.filePath release];
[super dealloc];
}
#end
or like this ....
#interface ActiveFeeds : NSObject {
NSMutableDictionary *invDictionary;
NSString *filePath;
}
#end
#implementation ActiveFeeds
- (id)init{
self = [super init];
if (self != nil){
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
invDictionary = [dictionary mutableCopy];
[dictionary release];
}
}
return self;
}
/* And use invDictionary all in the application */
- (void)setObjectAtKey:(NSMutableDictionary *)objectDic atKey:(NSString *)setKey{
[invDictionary setObject:objectDic forKey:setKey];
}
- (void)dealloc {
[invDictionary release];
[filePath release];
[super dealloc];
}
#end
Please any one help me to get the correct way of using the variables ....
- (id)initWithFilePath:(NSString *)path{
self = [super init];
if (self != nil){
self.filePath = path;
self.invDictionary = [NSMutableDictionary dictionaryWithContentsOfFile:path];
}
return self;
}
also
- (void)dealloc {
[invDictionary release];
[filePath release];
[super dealloc];
}