This question already has answers here:
How to save NSMutablearray in NSUserDefaults
(9 answers)
Closed 5 years ago.
In one view controller, I store some array value and I will get that value from another view controller.
How to save array value in shared manager and how to retrieve that array value from another view controller? How to use shared preference in Xcode? Is that possible? Please help me with the example.Thank you.
my code is
(id)sharedManager {
static AssistantView *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
and i put the value
[[AssistantView sharedManager]results]; // where results is array
Use NSUserDefaults
Set
[[NSUserDefaults standardUserDefaults] setObject:#"Your Object" forKey:#"NameOfPreference"];
[[NSUserDefaults standardUserDefaults] synchronize];
Get
NSString *savedObject = [[NSUserDefaults standardUserDefaults]
stringForKey:#"NameOfPreference"];
// its Your Object
Alternative using AppDelegate
1 Define Macro
#define APPDELEGATE ((AppDelegate *)[[UIApplication sharedApplication] delegate])
2 add property for object in Appdelegate
#property (nonatomic) NSArray *arrObjects;
3 set object to property .
APPDELEGATE.arrObjects = #[#"",#""];
4 Get value
NSArray *globalObjects = APPDELEGATE.arrObjects
you should use a singleton class like this
#import <foundation/Foundation.h>
#interface MySingleton : NSObject {
}
#property (nonatomic, retain) NSArray *mySharedArray;
+(id)sharedMySingleton;
#end
and in .m file
#implementation MySingleton
static MySingleton* _sharedMySingleton = nil;
+(id)sharedMySingleton
{
#synchronized([MySingleton class])
{
if (!_sharedMySingleton)
_sharedMySingleton = [[self alloc] init];
return _sharedMySingleton;
}
return nil;
}
and call it in any viewController like
[[MySingleton sharedMySingleton] mySharedArray];
1) Create a File with NSObject as subclass (i.e SharedClass)
SharedClass.m
#implementation SharedClass
+ (instancetype)sharedManager {
static SharedClass *sharedManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedManager = [[self alloc] init];
});
return sharedManager;
}
- (instancetype)init {
if (self = [super init]) {
// alloc or set object here
return self;
}
SharedClass.h
#import <Foundation/Foundation.h>
#interface SharedClass : NSObject
+ (instancetype)sharedManager;
// your array
#end
2) To access array
[[SharedClass sharedManager]array];
3) To set array
[[SharedClass sharedManager]setArray];
Related
I want to make one single method and call it, to many view controllers. Help me? and i also want to alloc UIView or button or label on that Fixed View.
HERE IS MY CODE
.h
#import <UIKit/UIKit.h>
#interface UIOnlyView : UIView
+ (UIOnlyView *) sharedGlobalClass;
-(void)yourMethod;
#end
.m
+(UIOnlyView *)sharedGlobalClass {
static dispatch_once_t pred;
static id shared = nil;
dispatch_once(&pred, ^{
shared = [[super alloc] init];
});
return shared;
}
-(void)yourMethod{
NSLog(#"Method called");
UIView *customView=[[UIView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
customView.backgroundColor=[UIColor redColor];
[self addSubview:customView];
}
But my Custom view is not show on my view controller class where i called this method.
Use a singleton like this
create a class for example GlobalClass with type NSObject
In .h class create this method
+ (GlobalClass *) sharedGlobalClass;
- (void) yourMethod : (UIView *) view;
Now in .m class
+ (GlobalClass *) sharedGlobalClass {
static dispatch_once_t pred;
static id shared = nil;
dispatch_once(&pred, ^{
shared = [[super alloc] init];
});
return shared;
}
- (void) yourMethod : (UIView *) view {
UIView *customView=[[UIView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
customView.backgroundColor=[UIColor redColor];
[view addSubview:customView];
}
Now you can call this method like this
[[GlobalClass sharedGlobalClass] yourMethod:self.view];
from any of your ViewController, you just have to import
#import "GlobalClass.h"
In Objective C:
#interface OUCSCalendarManager ()
- (void)globalMethod;
#end
#implementation OUCSCSharedManager
/// ------------------------------------------------------------------------
/// Singleton Method
///--------------------------------------------------------------------------
+(instancetype)SharedManager{
#synchronized(self) {
static OUCSCalendarManager *sharedInstance = nil;
static dispatch_once_t pred;
#synchronized (self) {
dispatch_once(&pred, ^{
sharedInstance = [[OUCSCalendarManager alloc]init];
});
return sharedInstance;
}
}
}
- (void)globalMethod {
}
}
To Call That method from anywhere in project you need to create the singleton object and call method like this
[[OUCSCalendarManager calendarSharedManager]globalMethod];
Let me know if you face any issue.
ClassA.h
#import "ClassA.h"
#interface ClassA : NSObject
+(id)sharedInstance;
-(void)customMethod;
#end
Now Implementation of ClassA.m
#import "ClassA.h"
#implementation ClassA
+(id)sharedInstance
{
static ClassA *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[ClassA alloc] init];
});
return instance;
}
-(void)customMethod
{
//Method body
}
Now import the header file in other viewcontrollers and use it like
[[ClassA sharedInstance] customMethod{}];
You can use the singleton class for this purpose:
create a NSObject class:
import <foundation/Foundation.h>
#interface MyManager : NSObject {
NSString *someProperty;
}
#property (nonatomic, retain) NSString *someProperty;
+ (id)sharedManager;
#end
In your .m file:
import "MyManager.h"
#implementation MyManager
#synthesize someProperty;
+ (id)sharedManager {
static MyManager *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
you can use the someProperty globally in all class.
it defines a static variable initialised once and only once in sharedManager.
for more info: http://www.galloway.me.uk/tutorials/singleton-classes/
https://code.tutsplus.com/articles/design-patterns-singletons--cms-23886
I've been trying to implement a global NSMutableArray from what I think to be a singleton class that I've implemented.
I can enter ViewController # 2, add and remove objects to the array.
However, when I leave ViewController #2 and come back, the data does not persist, and I have an array with 0 objects.
What do you think I'm doing wrong?
.h
// GlobalArray.h
#interface GlobalArray : NSObject{
NSMutableArray* globalArray;
}
+(void)initialize;
.m
#import "GlobalArray.h"
#implementation GlobalArray
static GlobalArray* sharedGlobalArray;
NSMutableArray* globalArray;
+(void)initialize{
static BOOL initalized = NO;
if(!initalized){
initalized = YES;
sharedGlobalArray = [[GlobalArray alloc] init];
}
}
- (id)init{
if (self = [super init]) {
if (!globalArray) {
globalArray = [[NSMutableArray alloc] init];
}
}
return self;
}
View Controller #2
GlobalArray* myGlobalArray;
myGlobalArray = [[GlobalArray alloc] init];
//Various add and remove code
Thank you for your input.
Following is best approach to share data Globally at Application level. Singleton Class is a key. Singleton is only initialised once, rest of times shared data is returned.
#interface Singleton : NSObject
#property (nonatomic, retain) NSMutableArray * globalArray;
+(Singleton*)singleton;
#end
#implementation Singleton
#synthesize globalArray;
+(Singleton *)singleton {
static dispatch_once_t pred;
static Singleton *shared = nil;
dispatch_once(&pred, ^{
shared = [[Singleton alloc] init];
shared.globalArray = [[NSMutableArray alloc]init];
});
return shared;
}
#end
Following is the way to access/use shared data.
NSMutableArray * sharedData = [Singleton singleton].globalArray;
You create separate instance of GlobalArray in your ViewController#2 with this code:
GlobalArray* myGlobalArray;
myGlobalArray = [[GlobalArray alloc] init];
Instead, you should create accessor method to return your shared instance, something like this:
// GlobalArray.h
#interface GlobalArray : NSObject{
NSMutableArray* globalArray;
}
+(void)initialize;
+(GlobalArray*)sharedInstance;
with implementation:
// GlobalArray.m
// ... your existing code
// accessor method
+(GlobalArray*)sharedInstance
{
return sharedGlobalArray;
}
and then call it from your ViewController#2:
GlobalArray* myGlobalArray = [GlobalArray sharedInstance];
However, using global variables to transfer data between view controllers is bad practice; I suggest you to use more safe methods, create a delegate, for example.
To create a shared global array, if that's really what you want, just put this in the header file:
extern NSMutableArray *myGlobalArray;
and this in your main source file:
NSMutableArray *myGlobalArray;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
myGlobalArray = [NSMutableArray new];
}
Use this code for set and get the array views, for adding and removing do it separate in controller itself.
// GlobalArray.h
#interface GlobalArray : NSObject
#property (nonatomic, strong) NSMutableArray* globalArray;
+ (id)sharedManager;
-(NSMutableArray *) getGlobalArray;
-(void) setGlobalArray:(NSMutableArray *)array;
#end
/*-----------------------------------------*/
#import "GlobalArray.h"
#implementation GlobalArray
+ (id)sharedManager {
static GlobalArray *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
- (id)init{
if (self = [super init]) {
if (!globalArray) {
globalArray = [[NSMutableArray alloc] init];
}
}
return self;
}
-(NSMutableArray *) getGlobalArray{
return self.globalArray;
}
-(void) setGlobalArray:(NSMutableArray *)array{
_globalArray = globalArray;
}
#end
-------------------------
//get array
NSArray * array = [[GlobalArray sharedManager] getGlobalArray];
//set array
[[GlobalArray sharedManager] setGlobalArray:array]
-------------------------
I made a singleton and i'm trying to add objects to self.timelineArray but i can't. When i do this i have 9 objects:
NSNumber* nmb = [[NSNumber alloc] initWithInt:1];
[self.dataManager.timelineArray addObject:nmb];
After i insert the nmb object, i still have 9 objects.
Here's my singleton header (only important bits):
#interface DataManager : NSObject
#property (nonatomic, strong) NSMutableArray* timelineArray;
Here's my singleton implementation (only important bits):
#import "DataManager.h"
static DataManager* sharedInstance = nil;
#implementation DataManager
+ (DataManager *) sharedInstance{
#synchronized(self)
{
if (sharedInstance == nil)
sharedInstance = [[self alloc] init];
}
return sharedInstance;
}
- (id)init {
if (self = [super init])
{
self.timelineArray = [[NSMutableArray alloc] init];
}
return self;
}
This is just simple coding and i can't seem to figure out why it does not work.
Trying to modify immutable array(NSArray) will lead to this.
Replace
[responseObject objectForKey:#"timeline"] with [[NSMutableArray alloc] initWithArray:[responseObject objectForKey:#"timeline"]
This was based on the comments of the question.
i'll suggest you to add like following
NSNumber* nmb = [[NSNumber alloc] initWithInt:1];
[[DataManager sharedInstance]timelineArray addObject:nmb];
this will always add into the singleton not the instance of singleton
I need to access a NSManagedObject that gets set in another class, so I tried making a singleton that looks like this:
MyManager.h
#import <CoreData/CoreData.h>
#import <foundation/Foundation.h>
#interface MyManager : NSObject {
NSManagedObject *someProperty;
}
#property (nonatomic, retain) NSManagedObject *someProperty;
+ (id)sharedManager;
#end
MyManager.m
#import "MyManager.h"
#implementation MyManager
#synthesize someProperty;
#pragma mark Singleton Methods
+ (id)sharedManager {
static MyManager *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
- (id)init {
if (self = [super init]) {
someProperty = nil;
}
return self;
}
- (void)dealloc {
// Should never be called, but just here for clarity really.
}
#end
I set in one class like this:
MyManager *sharedManager = [MyManager sharedManager];
sharedManager.someProperty = self.form;
but when I log it, it is null
NSLog(#"shared::%#", sharedManager.someProperty);
Im new to singletons so could use some advice.
You should just fetch it again from the class U need it, but remember to save context before if U were changing it in that other class or thread...
In core data, you cannot just set a property, you either insert a new object that particular entity or fetch it and used the fetched object to set property. I hope that when you are doing "set", you have created nsmanagedobject by insertion or fetch. If not, that might be the reason why it is null.
NSManagedObject *someEntity = [NSEntityDescription insertNewObjectForEntityForName:#"someEntity" inManagedObjectContext:context];
//after this
someEntity.stringProperty = #"Blablabla";
I have a complete noob question for you. I'm obviously rusty with obj-c. I have a simple shopping cart class implemented as a singleton and just want it to store a single NSMutableDictionary. I want to be able to add objects to this dictionary from anywhere in the app. But for some (I'm sure simple) reason it's just returning null. No error messages.
ShoppingCart.h:
#import <Foundation/Foundation.h>
#interface ShoppingCart : NSObject
// This is the only thing I'm storing here.
#property (nonatomic, strong) NSMutableDictionary *items;
+ (ShoppingCart *)sharedInstance;
#end
ShoppingCart.m:
// Typical singelton.
#import "ShoppingCart.h"
#implementation ShoppingCart
static ShoppingCart *sharedInstance = nil;
+ (ShoppingCart *)sharedInstance
{
#synchronized(self)
{
if (sharedInstance == nil)
sharedInstance = [[self alloc] init];
}
return(sharedInstance);
}
#end
And in my VC I'm trying to set it with:
- (IBAction)addToCartButton:(id)sender
{
NSDictionary *thisItem = [[NSDictionary alloc] initWithObjects:#[#"test", #"100101", #"This is a test products description"] forKeys:#[#"name", #"sku", #"desc"]];
// This is what's failing.
[[ShoppingCart sharedInstance].items setObject:thisItem forKey:#"test"];
// But this works.
[ShoppingCart sharedInstance].items = (NSMutableDictionary *)thisItem;
// This logs null. Specifically "(null) has been added to the cart"
DDLogCInfo(#"%# has been added to the cart", [[ShoppingCart sharedInstance] items]);
}
Thanks
You are never creating a NSMutableDictionary object named items.
You could create it in the init of ShoppingCart.
-(id)init
{
if(self = [super init]) {
_items = [NSMutableDictionary dictionary];
}
return self;
}
or in sharedInstance
+ (ShoppingCart *)sharedInstance
{
#synchronized(self)
{
if (sharedInstance == nil)
sharedInstance = [[self alloc] init];
sharedInstance.items = [NSMutableDictionary dictionary];
}
return(sharedInstance);
}
I might also add it's better (arguably) to set up your shared instance like so:
static ShoppingCart *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
instance.items = [NSMutableDictionary dictionary];
});
return instance;