I'm trying to write the state of a UISwitch to file, so every time the app starts up it remembers whether it was on or off previously.
-(IBAction) switchValueChanged {
if (Hard1ON.on) {
isH1 = (#"YES");
//save above yes to file
After a bit of searching, I found this is the piece of code used to save to file:
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError **)error
However it is evoking a 'Use of undeclared identifier 'writeToFile' error. Can anyone tell me what's wrong?
To save to a file as a string (likely not the best solution):
- (IBAction)switchValueChanged:(id)sender
{
NSString *stateAsString;
if ([sender isOn]) {
stateAsString = #"YES";
} else {
stateAsString = #"NO";
}
[stateAsString
writeToFile:#"/path/to/file"
atomically:NO
encoding:NSUTF8StringEncoding
error:NULL
];
}
It would probably be a better idea to write the state to NSUserDefaults:
#define kSwitchStateKey #"SwitchState"
- (IBAction)switchValueChanged:(id)sender
{
[[NSUserDefaults standardUserDefaults]
setObject:#([sender isOn)
forKey:kSwitchStateKey
];
}
Related
I have a UISwitch which is used to mute the sound effects with.
When switch is set ON the sound effects are mute.
The state is saved using NSUserDefaults. It works great. But when the app is started from the very first time after installing it, and you got to the settings and the switch is set to OFF but there is no sound. But if i press the switch on then off again the sound effect works.
How do i do to set switch default value to OFF.
I have seen similar exempels but i don't get it to work.
In the first ViewController i have this code:
- (void)viewDidLoad {
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
if ([[NSUserDefaults standardUserDefaults]objectForKey:#"switchKeyLjud"]==nil)
{
[[standardDefaults stringForKey:#"switchKeyLjud"] isEqual: #"off"];
}
if ([[standardDefaults stringForKey:#"switchKeyLjud"] isEqual: #"off"]) {
ImageViewLjud.hidden = YES;
}
}
and in the settings ViewController:
- (void)viewDidLoad {
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
self->switchOutletLjud.on = ([[standardDefaults stringForKey:#"switchKeyLjud"]
isEqualToString:#"On"]) ? (YES) : (NO);
if ([[standardDefaults stringForKey:#"switchKeyLjud"] isEqual: #"On"]) {
[ImageViewLjud setImage:[UIImage imageNamed:#"ljudOFF.png"]];
}
else {
[ImageViewLjud setImage:[UIImage imageNamed:#"ljudON.png"]];
}
}
and this is the switch
- (IBAction)switchLjudChanged:(UISwitch *)sender {
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
if (sender.on == 0) {
[standardDefaults setObject:#"Off" forKey:#"switchKeyLjud"];
} else if (sender.on == 1) {
[standardDefaults setObject:#"On" forKey:#"switchKeyLjud"];
}
if ([[standardDefaults stringForKey:#"switchKeyLjud"] isEqual: #"On"]) {
[ImageViewLjud setImage:[UIImage imageNamed:#"ljudOFF.png"]];
}
else {
[ImageViewLjud setImage:[UIImage imageNamed:#"ljudON.png"]];
}
[standardDefaults synchronize];
}
Thanks for any help!!
It looks like a very simple error in your sample code:
- (void)viewDidLoad {
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
if ([[NSUserDefaults standardUserDefaults]objectForKey:#"switchKeyLjud"]==nil)
{
[[standardDefaults stringForKey:#"switchKeyLjud"] isEqual: #"off"];
}
The logic in this case doesn't actually set the "off" key, you're only evaluating it. First you check if it's nil. If it's nil, then you check if it is equal to "off". If it's nil, it can't also be equal to "off". I think what you want to be doing, in the event that it is initially nil, is then setting it to off:
[standardDefaults setString:#"off" forKey:#"switchKeyLjud"];
Looks like a simple typo.
Additionally, consider setting the BOOL values directly in your user defaults, rather then relying on strings and then translating those back and forth to BOOL values in code. Unless you have a specific need to store them as strings in NSUserDefaults, avoid the additional point of failure.
I have multiple views where I need to handle the network connection of socket.io, so I created singleton class namely MC_SocketHandler. Below is the code of the MC_SocketHandler class.
// MC_SocketHandler.h
#import <Foundation/Foundation.h>
#import "SocketIO.h"
#interface MC_SocketHandler : NSObject <SocketIODelegate>
// SocketIO
//#property (nonatomic) SocketIO *socketConnection;
+ (MC_SocketHandler *) sharedSocketHanderObj;
+ (SocketIO *) initHandShake;
+ (SocketIO *) getSocketConnection;
-(bool) isConnected;
-(void) disConnect;
-(void) fireAgentLeftChat;
#end
// MC_SocketHandler.m
#import "MC_SocketHandler.h"
#import "MC_APIUtility.h"
#implementation MC_SocketHandler
SocketIO *socketConnection = nil;
static MC_SocketHandler *sharedSocketObj = nil;
+ (MC_SocketHandler *) sharedSocketHanderObj {
if (sharedSocketObj == nil)
sharedSocketObj = [[MC_SocketHandler alloc] init];
return sharedSocketObj;
}
+(SocketIO*) initHandShake {
if (socketConnection == nil) {
NSDictionary *headers = [NSDictionary dictionaryWithObjectsAndKeys:[MC_APIUtility getApiToken], #"token", nil];
socketConnection = [[SocketIO alloc] initWithDelegate:(id)self ];
[socketConnection connectToHost:domain onPort:447 withParams:headers];
}
return socketConnection;
}
+ (SocketIO *) getSocketConnection {
return socketConnection;
}
-(bool) isConnected {
if (socketConnection == nil)
return socketConnection.isConnected;
return false;
}
-(void) disConnect {
if (socketConnection != nil && socketConnection.isConnected)
[socketConnection disconnect];
NSLog(#"Disconnected --- %hhd", socketConnection.isConnected );
return;
}
// SocketIO Delegate
-(void) socketIODidConnect:(SocketIO *)socket {
NSLog(#"Socket has Connected....");
}
-(void) socketIO:(SocketIO *)socket didReceiveEvent:(SocketIOPacket *)packet {
NSString *data = packet.data;
NSLog(#"---- didReceoveEvent - data - %#", data);
// Grab data from packet
NSDictionary *dict = packet.dataAsJSON;
NSLog(#"EVENT DATA :- %# DICT :- %#", data, dict);
/*
EVENTS To Listen
onSuccessInit
visitor_info
new_visitor
agent_online
agent_offline
agent_logout
*/
dict = nil;
// Pull out args fro mdict
//NSArray *args = dict[#"args"];
}
-(void) socketIO:(SocketIO *)socket didReceiveMessage:(SocketIOPacket *)packet {
NSLog(#"Rcvd Message - %#", packet.data);
}
-(void) socketIO:(SocketIO *)socket didSendMessage:(SocketIOPacket *)packet {
NSLog(#"Send Msg - %#", packet.dataAsJSON);
}
-(void) socketIO:(SocketIO *)socket onError:(NSError *)error {
NSLog(#"Error - %#", error);
}
-(void) socketIODidDisconnect:(SocketIO *)socket disconnectedWithError:(NSError *)error {
NSLog(#"Disconnected With Error - %#", error);
}
-(void) fireAgentLeftChat {
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:[MainAppDataObject sharedAppDataObject].activeAgentChatItem.chatSessionId forKey:#"chat_session_id"];
[socketConnection sendEvent:#"agentLeftChat" withData:dict];
return;
}
- (void)dealloc {
socketConnection = nil;
}
#end
Code that I use it in 1 of my views :
// Init SocketIO
SocketIO *socket = [MC_SocketHandler initHandShake];
// Fire Agent Online event
[socket sendEvent:#"setAgentOnline" withData:nil];
Handshake is being done properly, setAgentOnline event is send properly. Other events that I fire are also done properly. BUT,
when socket gets connected thru initHandshake, I believe "Socket has Connected...." should be seen in logs as that is written in socketIODidConnect delegate method. Similarly, I receive event (I see logs of socket.m class), but my delegate method didReceiveEvent is never called. Same way I don't see any logs of any delegate methods.
In initHandShake method only I have set the delegate also :
socketConnection = [[SocketIO alloc] initWithDelegate:(id)self ];
yet why these methods aren't called.
I was also wondering, when I receive events, on different events I got to perform different actions. How will I transfer to particular view (View's obj won't be shared with this to call his method) ? And If I create delegate, then I will have to handle all delegate methods in all views. What's will be the best method to work out with this ? And why this Singleton & delegate methods aren't being linked & called when I have set the delegate. Where am I going wrong ?
Any help, guidance is highly appreciative. Thanks alot.
In SocketIO, you create a SocketIO
Is that right?
In fact called "socketConnection". Am i right?
AT THAT TIME...
you must set the delegate !!!
Essentially, your code must look like this,
socketConnection = make one of these.
socketConnection.delegate = self;
It's possible this is your fundamental problem. I hope it helps!
PS you should, almost certainly, use only properties in iOS development. get rid of your "traditional" variables and use only properties.
Hi I'm new to using blocks in Objective-C
What I think I want is the following:
- (void) iNeedAToken {
NSString *token = [self theMethodThatShouldReturnTheToken];
}
- (NSString) theMethodThatShouldReturnTheToken {
[myAwesomeAsyncMethod success:^(id JSON) {
NSString *token = [JSON objectForKey:#"FOO"];
return token;
}]
}
Is this possible? Or is this the wrong logic all together?
Thanks!
You're mixing async with synchronous code. You're theMethodThatShouldReturnTheToken already returned (you're missing a return value) before the block passed to success finishes.
Best bet would be to continue your process from the success block.
- (void) tokenRequestContext1
{
[self requestToken:^(NSString *token) {
// do something with token
}];
}
- (void) requestToken:(void(^)(NSString *))tokenBlock
{
[myAwesomeAsyncMethod success:^(id JSON) {
NSString *token = [JSON objectForKey:#"FOO"];
if (tokenBlock) {
tokenBlock(token);
}
}];
}
You start by calling requestToken. This will start the async request for your token. Some time might pass, but eventually doSomethingWithToken will be called where you can use the received token.
There is a description of way to wait until complition block will be finished: http://omegadelta.net/2011/05/10/how-to-wait-for-ios-methods-with-completion-blocks-to-finish/
Regular version of this code is:
- (void) iNeedAToken {
[self theMethodThatShouldReturnTheToken:^(id res){ token = res;}];
NSString *token = [self theMethodThatShouldReturnTheToken];
}
- (void) theMethodThatShouldReturnTheToken:(void (^)(id res)result) {
[myAwesomeAsyncMethod success:^(id JSON) {
NSString *token = [JSON objectForKey:#"FOO"];
result(token);
}]
}
I am using MenuLevel in my game for loading levels.. http://www.prioregroup.com/iphone/menulevel.aspx
At the moment, whether a level is locked or not, it's loading.. If it's locked, it should not be loading.. How can I do that? Thanks..
// create menu item
[menu createMenuItemLevel:1 position:ccp(x, size.height / 2) life:0 locked:NO];
- (void)menuLevel:(MenuLevel *)menuLevel buttonSelected:(id)source
{
CCMenuItem *item = (CCMenuItem*)source;
NSString *msg = [NSString stringWithFormat:#"You have pressed the button # %d", item.tag]; // retrieve level number..
NSLog(#"MenuLevel Sample %#", msg);
// What I want is something like.. if (item.locked == YES) do something
}
You can use the userData property. In your MenuLevel.m file add the following lines in
- (CCMenuItem*)createMenuItemLevel:(NSInteger)level
position:(CGPoint)position
life:(NSInteger)life
locked:(BOOL)locked
target:(id)target
selector:(SEL)selector
method.
if (locked)
{
item.userData = #"locked";
}
else
{
item.userData = #"notLocked";
}
And in your buttonSelected: method check that userData as given below:
NSString *lockString = (NSString *)item.userData;
if ([lockString isEqualToString:#"locked"])
{
// Locked level
}
else
{
// Unlocked
}
I am getting an error in my viewDidLoad. It is saying there is a undeclared identifier 'object'.
I'm new to this method of saving and retrieving data and I am not sure what to do.
//Viewcontroller.m
-(void)saveString:(UIImage*)myString
{
[[NSUserDefaults standardUserDefaults] setObject:myString forKey:#"image"];
}
- (IBAction)back:(id)sender {
[self saveString:object.image];
}
//ViewController2.m
-(UIImage*)retrieveString
{
UIImage* recoveredString = [[NSUserDefaults standardUserDefaults] objectForKey:#"image"];
return recoveredString;
}
- (void)viewDidLoad
{
object.image = [self retrieveString];
[super viewDidLoad];
}
You can't store an image in NSUserDefault, but you can store the path to it. So is not right to access NSUserDefault and pass the obeject for key image or viceversa. You can save it into your app sandbox and save the path to it. Then you can use class method [UIimage imageWithContentsOfFile:path];
By the way you can save it as a string of data char, but I don't think it worth it and you need a proper encoding and decoding. You can also try to save it as an NSData object after a proper conversion, NSUserDefault supports it.