NSDictionary recursive loop - ios

I'm using the following function in order to get all the keys and values of the preferences.plist file located in: /private/var/preferences/SystemConfiguration/preferences.plist
- (void)FindKeysAndValuesInPlist:(id)object forKeyNamed:(NSString *)keyName{
if ([object isKindOfClass:[NSDictionary class]])
{
NSLog(#"%#",keyName);
[object enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
[self FindKeysAndValuesInPlist:value forKeyNamed:key];
}];
}
else if ([object isKindOfClass:[NSArray class]])
{
[object enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[self FindKeysAndValuesInPlist:obj forKeyNamed:nil];
}];
}
else
{
NSLog(#"%#.%#", keyName, object);
}
}
An example of the content of preferences.plist:
{
CurrentSet = "/Sets/3B9E7BEB-5558-4497-803B-21B03E6A46C0";
NetworkServices = {
"014226AB-75B7-41CF-9B96-48E82FD6A395" = {
Interface = {
DeviceName = ip4;
Hardware = "com.apple.CommCenter";
Type = "com.apple.CommCenter";
UserDefinedName = "com.apple.CommCenter (ip4)";
};
PrimaryRank = Never;
UserDefinedName = "com.apple.CommCenter (ip4)";
"com.apple.CommCenter" = {
AllowNetworkAccess = 0;
Available = 1;
Version = 11;
};
};
"1C01B561-1A55-4E3B-82FC-CDFF5024F0D2" = {
Interface = {
DeviceName = ip1;
Hardware = "com.apple.CommCenter";
Type = "com.apple.CommCenter";
UserDefinedName = "com.apple.CommCenter (ip1)";
};
UserDefinedName = "com.apple.CommCenter (ip1)";
"com.apple.CommCenter" = {
AllowNetworkAccess = 1;
Available = 1;
SettingsHaveBeenAlteredByPreferences = 1;
Setup = {
apn = "";
password = "";
signature = <7ecb277c ad546563 3ac057fb db40aeaa 939f8c0e e7ae68c2 6e0ff602 77d3868d 18a63059 6c83f66d 46b8af57 d1bf83d0 2655ced6 57d773f4 5c7e733e 923aaa07 39165357 a4ecf270 130276f0 59c7470e 0b61a631 dff04fd1 0bc80cb4 a0dc0a03 96a8ebf0 74c24cdb 84c38239 9f6f7f05 ee032982 8ed1b72d b531405b 09e35f5b>;
"type-mask" = 0;
username = "";
};
Version = 11;
};
};
The problem is that I'm trying to create this kind of output format: MAINKEY.SUBKEY.VALUE
For example:
NetworkServices = {
"014226AB-75B7-41CF-9B96-48E82FD6A395" = {
Interface = {
DeviceName = ip4;
Hardware = "com.apple.CommCenter";
Type = "com.apple.CommCenter";
UserDefinedName = "com.apple.CommCenter (ip4)";
};
Would be: NetworkServices.014226AB-75B7-41CF-9B96-48E82FD6A395.Interface.Hardware.ip4

Iterate over the keys in a dictionary. When the value for a key is another dictionary, push the key onto a stack and recurse on the dictionary value. When the value is a string or number, then concatenate the keys in the stack and print the key path and value.
Code:
+ (void)printDict:(NSDictionary *)dict keyStack:(NSArray *)keys
{
if (keys == nil) {
keys = [NSArray array];
}
for (id key in dict) {
id value = dict[key];
if ([value respondsToSelector:#selector(objectForKey:)]) {
[self printDict:value keyStack:[keys arrayByAddingObject:key]];
} else {
NSLog(#"%# = %#", [[keys arrayByAddingObject:key] componentsJoinedByString:#"."], value);
}
}
}

Related

Obj-C: NSString crashes with error "Terminating app due to uncaught exception NSInvalidArgumentException"?

For some reason, the following line in my app is returned NULL, and thus, crashes my app:
NSString *address = [session user][#"field_street_address"][#"und"][0][#"safe_value"];
Which, I don't understand, as my console below states that data is returned for field_street_address. Is there something wrong with that line that I'm just not seeing? I've been staring at this for a while and I feel like I'm missing something obvious.
ViewController.m
NSDictionary *userDictInfo = (NSDictionary*) [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:#"diosSession"]];
DIOSSession *session = [DIOSSession sharedSession];
[session setUser:userDictInfo];
[session user];
NSString *address = [session user][#"field_street_address"][#"und"][0][#"safe_value"];
Console ([session user] log):
2017-10-06 14:06:22.226970-0700 app[828:193706] {
sessid = "DRY0fOXtO_FZOIeowFVVq8oalaFnKSe";
"session_name" = SESS2bb8896be0f16543ff3c6a;
token = giCdHBuw967IaSxDB34m0Evzf1HI3DIK6;
user = {
access = 1507310936;
created = 1459875505;
data = {
"ckeditor_auto_lang" = t;
"ckeditor_default" = t;
"ckeditor_lang" = en;
"ckeditor_show_toggle" = t;
"ckeditor_width" = "100%";
};
"field_address" = {
und = (
{
format = "<null>";
"safe_value" = "1325 Fake Street";
value = "1325 Fake Street";
}
);
};
"field_childrenunder" = {
und = (
{
format = "<null>";
"safe_value" = No;
value = No;
}
);
};
"field_city" = {
und = (
{
format = "<null>";
"safe_value" = Van;
value = Van;
}
);
};
"field_emergency_facility" = {
und = (
{
format = "<null>";
"safe_value" = Yes;
value = Yes;
}
);
};
"field_first_name" = {
und = (
{
format = "<null>";
"safe_value" = Brittany;
value = Brittany;
}
);
};
"field_last_name" = {
und = (
{
format = "<null>";
"safe_value" = B;
value = B;
}
);
};
"field_phonenumber" = {
und = (
{
format = "<null>";
"safe_value" = 2369893091;
value = 2369893091;
}
);
};
"field_photo_path" = {
und = (
{
format = "<null>";
"safe_value" = "sites/default/files/stored/1507092784.jpg";
value = "sites/default/files/stored/1507092784.jpg";
}
);
};
"field_points_balance" = {
und = (
{
format = "<null>";
"safe_value" = 12;
value = 12;
}
);
};
"field_postal_code" = {
und = (
{
format = "<null>";
"safe_value" = 000000;
value = 000000;
}
);
};
"field_private_message_notify" = {
und = (
{
value = 1;
}
);
};
"field_profile_photo" = {
und = (
{
alt = "";
fid = 237;
"field_file_image_alt_text" = (
);
"field_file_image_title_text" = (
);
filemime = "image/jpeg";
filename = "1507092784.jpg";
filesize = 16084;
height = 296;
metadata = {
height = 296;
width = 300;
};
"rdf_mapping" = (
);
status = 1;
timestamp = 1507108254;
title = "";
type = image;
uid = 47;
uri = "public://stored/1507092784.jpg";
width = 300;
}
);
};
"field_property_type" = {
und = (
{
format = "<null>";
"safe_value" = House;
value = House;
}
);
};
"field_province" = {
und = (
{
format = "<null>";
"safe_value" = BC;
value = BC;
}
);
};
"field_special_skills" = {
und = (
{
format = "<null>";
"safe_value" = "Oral medication";
value = "Oral medication";
}
);
};
"field_star_rating" = {
und = (
{
format = "<null>";
"safe_value" = 1;
value = 1;
}
);
};
"field_street_address" = {
und = (
{
format = "<null>";
"safe_value" = "1325 Fake Street";
value = "1325 Fake Street";
}
);
};
"field_supervision" = {
und = (
{
format = "<null>";
"safe_value" = No;
value = No;
}
);
};
"field_userbio" = {
und = (
{
format = "<null>";
"safe_value" = "Hi my name is Brittany.";
value = "Hi my name is Brittany.";
}
);
};
language = "";
login = 1507320712;
mail = "brittany-b#shaw.ca";
name = Brittany;
picture = "<null>";
"rdf_mapping" = {
homepage = {
predicates = (
"foaf:page"
);
type = rel;
};
name = {
predicates = (
"foaf:name"
);
};
rdftype = (
"sioc:UserAccount"
);
};
roles = {
2 = "authenticated user";
};
signature = "";
"signature_format" = "filtered_html";
status = 1;
theme = "";
timezone = UTC;
uid = 47;
};
}
If the log output in your question is from logging [session user] then you need to first access the #"user" key.
NSString *address = [session user][#"user"][#"field_street_address"][#"und"][0][#"safe_value"];
BTW - for issues like this it really helps to break down the code:
NSDictionary *sessionUser = [session user];
NSDictionary *user = sessionUser[#"user"];
NSDicitonary *streetAddr = user[#"field_street_address"];
// etc.
Then you can see where you start getting nil and look at the previous results to determine where things are going wrong.

Update value or Set new key & value in NSMutableDictionary in Objective-C

I have an array of names and want to count them by having A & B prefix.
For example for this username I want my NSMutableDictionary *cellNum to return the count of names starting with each alphabet, like: "A":"2" & "B":"1".
#interface ...
{
NSArray *users;
NSMutableDictionary *cellNum;
}
#implementation ...
{
users = #[#"Ali",#"Armita",#"Babak"];
for (int i=0;i<users.count;i++)
{
if ( [users[i] hasPrefix:#"A"] )
{
cellNum[#"a"] = #([cellNum[#"a"] intValue]+1);
}
else
{
cellNum[#"b"] = #([cellNum[#"b"] intValue]+1);
}
}
}
Try using this code:
NSMutableDictionary *cellNum = [NSMutableDictionary dictionary];
[cellNum setObject:#(0) forKey:#"a"];
[cellNum setObject:#(0) forKey:#"b"];
NSArray* users = #[#"Ali",#"Armita",#"Babak"];
for (int i=0;i<users.count;i++)
{
if ( [users[i] hasPrefix:#"A"] ) {
cellNum[#"a"] = #([cellNum[#"a"] intValue]+1);
} else {
cellNum[#"b"] = #([cellNum[#"b"] intValue]+1);
}
}
This will surely Give you the desired result: { a = 2; b = 1; }

iOS MFI controller connection issue

i have this code that is a Plugin for Unreal Engine 4 is to allow MFI game controllers (Physical Bluetooth Gamepad, Joystick) to be used in my game on iOS devices
the plugin works fine if the game (App) is launched before connecting the controller
the problem is if the game controller is connected before launching the game the game crashes after the splash screen
also disconnecting the controller whilst the game is running closes/crashes the game
any advice is much appreciated
#include "IOSInputInterfacePrivatePCH.h"
#include "IInputInterface.h"
#include "IOSGamepad.h"
/** Beginning of FGCControllerNotificationHandler class */
#if PLATFORM_IOS
#interface FGCControllerNotificationHandler : NSObject
#property FIOSGamepad* device;
+ (id)sharedInstance;
#end
#implementation FGCControllerNotificationHandler
#synthesize device;
- (id)init
{
self = [super init];
return self;
}
+ (id)alloc
{
return [super allocWithZone:NULL];
}
+ (id)allocWithZone:(NSZone *)zone {
return [[self sharedInstance] retain];
}
- (id)copyWithZone:(NSZone *)zone {
return self;
}
- (id)retain {
return self;
}
- (NSUInteger)retainCount {
return NSUIntegerMax; /** denotes an object that cannot be released */
}
- (oneway void)release {
/** never release */
}
- (id)autorelease {
return self;
}
- (void)dealloc {
[super dealloc];
}
+ (FGCControllerNotificationHandler *)sharedInstance
{
static FGCControllerNotificationHandler* instance;
#synchronized(self)
{
if (instance == nil)
{
instance = [[self alloc] init];
}
}
return instance;
}
- (void)registerObservers:(FIOSGamepad *)inDevice
{
self.device = inDevice;
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
/** Assign controller when connected */
[center addObserver:self
selector:#selector(setupControllers)
name:GCControllerDidConnectNotification
object:nil];
/** Do something after controller disconnection */
[center addObserver:self
selector:#selector(cleanControllers)
name:GCControllerDidDisconnectNotification
object:nil];
/** Search for another controller */
[GCController startWirelessControllerDiscoveryWithCompletionHandler:nil];
/** Assign controller id for known controllers */
if ([[GCController controllers] count] > 0)
{
[self setupControllers];
}
}
- (void)setupControllers
{
if(device != nil)
{
self.device->OnControllerConnected();
}
}
- (void)cleanControllers
{
if(device != nil)
{
self.device->OnControllerDisconnected();
}
}
- (int32)getControllerCount
{
return (int32)[[GCController controllers] count];
}
- (TArray<GCController *>)getConnectedControllers
{
TArray<GCController *> availableControllers;
for (GCController* c in [GCController controllers])
{
availableControllers.Add(c);
}
return availableControllers;
}
#end
#endif
/** End of FGCControllerNotificationHandler class */
/** Beginning of FIOSGamepad class */
FIOSGamepad::FIOSGamepad(const TSharedRef<FGenericApplicationMessageHandler>& InMessageHandler) :
MessageHandler(InMessageHandler)
{
#if PLATFORM_IOS
/** In the engine, all controllers map to xbox controllers for consistency */
IOSToXboxControllerMapping[0] = 0; // FaceButtonBottom
IOSToXboxControllerMapping[1] = 1; // FaceButtonRight
IOSToXboxControllerMapping[2] = 2; // FaceButtonLeft
IOSToXboxControllerMapping[3] = 3; // FaceButtonTop
IOSToXboxControllerMapping[4] = 4; // L1
IOSToXboxControllerMapping[5] = 5; // R1
IOSToXboxControllerMapping[6] = 6; // None
IOSToXboxControllerMapping[7] = 7; // None
IOSToXboxControllerMapping[8] = 8; // None
IOSToXboxControllerMapping[9] = 9; // None
IOSToXboxControllerMapping[10] = 10; // L2
IOSToXboxControllerMapping[11] = 11; // R2
IOSToXboxControllerMapping[12] = 12; // Dpad up
IOSToXboxControllerMapping[13] = 13; // Dpad down
IOSToXboxControllerMapping[14] = 14; // Dpad left
IOSToXboxControllerMapping[15] = 15; // Dpad right
IOSToXboxControllerMapping[16] = 16; // Left stick up
IOSToXboxControllerMapping[17] = 17; // Left stick down
IOSToXboxControllerMapping[18] = 18; // Left stick left
IOSToXboxControllerMapping[19] = 19; // Left stick right
IOSToXboxControllerMapping[20] = 20; // Right stick up
IOSToXboxControllerMapping[21] = 21; // Right stick down
IOSToXboxControllerMapping[22] = 22; // Right stick left
IOSToXboxControllerMapping[23] = 23; // Right stick right
Buttons[0] = FGamepadKeyNames::FaceButtonBottom;
Buttons[1] = FGamepadKeyNames::FaceButtonRight;
Buttons[2] = FGamepadKeyNames::FaceButtonLeft;
Buttons[3] = FGamepadKeyNames::FaceButtonTop;
Buttons[4] = FGamepadKeyNames::LeftShoulder;
Buttons[5] = FGamepadKeyNames::RightShoulder;
Buttons[6] = FGamepadKeyNames::SpecialRight;
Buttons[7] = FGamepadKeyNames::SpecialLeft;
Buttons[8] = FGamepadKeyNames::LeftThumb;
Buttons[9] = FGamepadKeyNames::RightThumb;
Buttons[10] = FGamepadKeyNames::LeftTriggerThreshold;
Buttons[11] = FGamepadKeyNames::RightTriggerThreshold;
Buttons[12] = FGamepadKeyNames::DPadUp;
Buttons[13] = FGamepadKeyNames::DPadDown;
Buttons[14] = FGamepadKeyNames::DPadLeft;
Buttons[15] = FGamepadKeyNames::DPadRight;
Buttons[16] = FGamepadKeyNames::LeftStickUp;
Buttons[17] = FGamepadKeyNames::LeftStickDown;
Buttons[18] = FGamepadKeyNames::LeftStickLeft;
Buttons[19] = FGamepadKeyNames::LeftStickRight;
Buttons[20] = FGamepadKeyNames::RightStickUp;
Buttons[21] = FGamepadKeyNames::RightStickDown;
Buttons[22] = FGamepadKeyNames::RightStickLeft;
Buttons[23] = FGamepadKeyNames::RightStickRight;
bNeedsControllerStateUpdate = true;
InitialButtonRepeatDelay = 0.2f;
ButtonRepeatDelay = 0.1f;
/** Initialize ControllerStates */
for (int32 ControllerIndex=0; ControllerIndex < MAX_NUM_IOS_CONTROLLERS; ++ControllerIndex)
{
FControllerState& ControllerState = ControllerStates[ControllerIndex];
FMemory::Memzero(&ControllerState, sizeof(FControllerState));
ControllerState.ControllerId = ControllerIndex;
}
[[FGCControllerNotificationHandler sharedInstance] registerObservers:this];
#endif
}
FIOSGamepad::~FIOSGamepad()
{
}
void FIOSGamepad::Tick(float DeltaTime)
{
}
void FIOSGamepad::SendControllerEvents()
{
#if PLATFORM_IOS
for (int32 ControllerIndex=0; ControllerIndex < MAX_NUM_IOS_CONTROLLERS; ++ControllerIndex)
{
FControllerState& ControllerState = ControllerStates[ControllerIndex];
if (!ControllerState.bIsConnected && bNeedsControllerStateUpdate)
{
ControllerState.bIsConnected = (ControllerIndex < ((int32) [[GCController controllers] count]));
}
if (ControllerState.bIsConnected)
{
bool CurrentStates[MAX_NUM_IOS_CONTROLLER_BUTTONS] = {0};
GCController* Controller = [GCController controllers][ControllerIndex];
if (Controller.extendedGamepad != nil)
{
GCExtendedGamepad* ExGamepad = Controller.extendedGamepad;
/** Check Analog state */
if(ControllerState.LeftXAnalog != ExGamepad.leftThumbstick.xAxis.value)
{
MessageHandler->OnControllerAnalog(FGamepadKeyNames::LeftAnalogX, ControllerState.ControllerId, ExGamepad.leftThumbstick.xAxis.value);
ControllerState.LeftXAnalog = ExGamepad.leftThumbstick.xAxis.value;
}
if(ControllerState.LeftYAnalog != ExGamepad.leftThumbstick.yAxis.value)
{
MessageHandler->OnControllerAnalog(FGamepadKeyNames::LeftAnalogY, ControllerState.ControllerId, ExGamepad.leftThumbstick.yAxis.value);
ControllerState.LeftYAnalog = ExGamepad.leftThumbstick.yAxis.value;
}
if(ControllerState.RightXAnalog != ExGamepad.rightThumbstick.xAxis.value)
{
MessageHandler->OnControllerAnalog(FGamepadKeyNames::RightAnalogX, ControllerState.ControllerId, ExGamepad.rightThumbstick.xAxis.value);
ControllerState.RightXAnalog = ExGamepad.rightThumbstick.xAxis.value;
}
if(ControllerState.RightYAnalog != ExGamepad.rightThumbstick.yAxis.value)
{
MessageHandler->OnControllerAnalog(FGamepadKeyNames::RightAnalogY, ControllerState.ControllerId, ExGamepad.rightThumbstick.yAxis.value);
ControllerState.RightYAnalog = ExGamepad.rightThumbstick.yAxis.value;
}
if(ControllerState.LeftTriggerAnalog != ExGamepad.leftTrigger.value)
{
MessageHandler->OnControllerAnalog(FGamepadKeyNames::LeftTriggerAnalog, ControllerState.ControllerId, ExGamepad.leftTrigger.value);
ControllerState.LeftTriggerAnalog = ExGamepad.leftTrigger.value;
}
if(ControllerState.RightTriggerAnalog != ExGamepad.rightTrigger.value)
{
MessageHandler->OnControllerAnalog(FGamepadKeyNames::RightTriggerAnalog, ControllerState.ControllerId, ExGamepad.rightTrigger.value);
ControllerState.RightTriggerAnalog = ExGamepad.rightTrigger.value;
}
/** Get the current state of all buttons */
CurrentStates[IOSToXboxControllerMapping[0]] = ExGamepad.buttonA.pressed;
CurrentStates[IOSToXboxControllerMapping[1]] = ExGamepad.buttonB.pressed;
CurrentStates[IOSToXboxControllerMapping[2]] = ExGamepad.buttonX.pressed;
CurrentStates[IOSToXboxControllerMapping[3]] = ExGamepad.buttonY.pressed;
CurrentStates[IOSToXboxControllerMapping[4]] = ExGamepad.leftShoulder.pressed;
CurrentStates[IOSToXboxControllerMapping[5]] = ExGamepad.rightShoulder.pressed;
CurrentStates[IOSToXboxControllerMapping[6]] = false;
CurrentStates[IOSToXboxControllerMapping[7]] = false;
CurrentStates[IOSToXboxControllerMapping[8]] = false;
CurrentStates[IOSToXboxControllerMapping[9]] = false;
CurrentStates[IOSToXboxControllerMapping[10]] = ExGamepad.leftTrigger.value > IOS_TRIGGER_THRESHOLD;
CurrentStates[IOSToXboxControllerMapping[11]] = ExGamepad.rightTrigger.value > IOS_TRIGGER_THRESHOLD;
CurrentStates[IOSToXboxControllerMapping[12]] = ExGamepad.dpad.up.pressed;
CurrentStates[IOSToXboxControllerMapping[13]] = ExGamepad.dpad.down.pressed;
CurrentStates[IOSToXboxControllerMapping[14]] = ExGamepad.dpad.left.pressed;
CurrentStates[IOSToXboxControllerMapping[15]] = ExGamepad.dpad.right.pressed;
CurrentStates[IOSToXboxControllerMapping[16]] = ExGamepad.leftThumbstick.up;
CurrentStates[IOSToXboxControllerMapping[17]] = ExGamepad.leftThumbstick.down;
CurrentStates[IOSToXboxControllerMapping[18]] = ExGamepad.leftThumbstick.left;
CurrentStates[IOSToXboxControllerMapping[19]] = ExGamepad.leftThumbstick.right;
CurrentStates[IOSToXboxControllerMapping[20]] = ExGamepad.rightThumbstick.up;
CurrentStates[IOSToXboxControllerMapping[21]] = ExGamepad.rightThumbstick.down;
CurrentStates[IOSToXboxControllerMapping[22]] = ExGamepad.rightThumbstick.left;
CurrentStates[IOSToXboxControllerMapping[23]] = ExGamepad.rightThumbstick.right;
}
else if (Controller.gamepad != nil)
{
GCGamepad* Gamepad = Controller.gamepad;
/** Get the current state of all buttons */
CurrentStates[IOSToXboxControllerMapping[0]] = Gamepad.buttonA.pressed;
CurrentStates[IOSToXboxControllerMapping[1]] = Gamepad.buttonB.pressed;
CurrentStates[IOSToXboxControllerMapping[2]] = Gamepad.buttonX.pressed;
CurrentStates[IOSToXboxControllerMapping[3]] = Gamepad.buttonY.pressed;
CurrentStates[IOSToXboxControllerMapping[4]] = Gamepad.leftShoulder.pressed;
CurrentStates[IOSToXboxControllerMapping[5]] = Gamepad.rightShoulder.pressed;
CurrentStates[IOSToXboxControllerMapping[6]] = false;
CurrentStates[IOSToXboxControllerMapping[7]] = false;
CurrentStates[IOSToXboxControllerMapping[8]] = false;
CurrentStates[IOSToXboxControllerMapping[9]] = false;
CurrentStates[IOSToXboxControllerMapping[10]] = false;
CurrentStates[IOSToXboxControllerMapping[11]] = false;
CurrentStates[IOSToXboxControllerMapping[12]] = Gamepad.dpad.up.pressed;
CurrentStates[IOSToXboxControllerMapping[13]] = Gamepad.dpad.down.pressed;
CurrentStates[IOSToXboxControllerMapping[14]] = Gamepad.dpad.left.pressed;
CurrentStates[IOSToXboxControllerMapping[15]] = Gamepad.dpad.right.pressed;
CurrentStates[IOSToXboxControllerMapping[16]] = false;
CurrentStates[IOSToXboxControllerMapping[17]] = false;
CurrentStates[IOSToXboxControllerMapping[18]] = false;
CurrentStates[IOSToXboxControllerMapping[19]] = false;
CurrentStates[IOSToXboxControllerMapping[20]] = false;
CurrentStates[IOSToXboxControllerMapping[21]] = false;
CurrentStates[IOSToXboxControllerMapping[22]] = false;
CurrentStates[IOSToXboxControllerMapping[23]] = false;
}
const double CurrentTime = FPlatformTime::Seconds();
/** For each button check against the previous state and send the correct message if any */
for (int32 ButtonIndex = 0; ButtonIndex < MAX_NUM_IOS_CONTROLLER_BUTTONS; ++ButtonIndex)
{
if(CurrentStates[ButtonIndex] != ControllerState.ButtonStates[ButtonIndex])
{
if(CurrentStates[ButtonIndex])
{
MessageHandler->OnControllerButtonPressed(Buttons[ButtonIndex], ControllerState.ControllerId, false);
}
else
{
MessageHandler->OnControllerButtonReleased(Buttons[ButtonIndex], ControllerState.ControllerId, false);
}
if(CurrentStates[ButtonIndex] == true)
{
/** this button was pressed - set the button's NextRepeatTime to the InitialButtonRepeatDelay */
ControllerState.NextRepeatTime[ButtonIndex] = CurrentTime + InitialButtonRepeatDelay;
}
}
else if(CurrentStates[ButtonIndex] == true && ControllerState.NextRepeatTime[ButtonIndex] <= CurrentTime)
{
MessageHandler->OnControllerButtonPressed(Buttons[ButtonIndex], ControllerState.ControllerId, true);
/** set the button's NextRepeatTime to the ButtonRepeatDelay */
ControllerState.NextRepeatTime[ButtonIndex] = CurrentTime + ButtonRepeatDelay;
}
/** Update the state for next time */
ControllerState.ButtonStates[ButtonIndex] = CurrentStates[ButtonIndex];
}
}
}
bNeedsControllerStateUpdate = false;
#endif
}
void FIOSGamepad::SetMessageHandler(const TSharedRef<FGenericApplicationMessageHandler>&InMessageHandler)
{
MessageHandler = InMessageHandler;
}
bool FIOSGamepad::Exec(UWorld* InWorld, const TCHAR* Cmd, FOutputDevice& Ar)
{
return false;
}
void FIOSGamepad::SetChannelValue (int32 ControllerId, FForceFeedbackChannelType ChannelType, float Value)
{
}
void FIOSGamepad::SetChannelValues (int32 ControllerId, const FForceFeedbackValues &values)
{
}
void FIOSGamepad::OnControllerConnected ()
{
for(int32 ControllerIndex=0; ControllerIndex < FMath::Min<int32>(MAX_NUM_IOS_CONTROLLERS, [[GCController controllers] count]); ++ControllerIndex)
{
[GCController controllers][ControllerIndex].playerIndex = (GCControllerPlayerIndex)ControllerIndex;
}
this->bNeedsControllerStateUpdate = true;
}
void FIOSGamepad::OnControllerDisconnected ()
{
this->bNeedsControllerStateUpdate = true;
}
/** End of FIOSGamepad class */

How to access NSArray inside a NSDictionary while parsing a xml?

I am using XMLReader to parse a xml response. I have converted the xml to a NSDictionary. Now i want to access the array named 'cTrx' inside the NSDictionary. This is my NSDictionary:
{
Envelope = {
Body = {
fRetrieveTransactionsforReversalResponse = {
fRetrieveTransactionsforReversalResult = {
pCellularNumber = {
text = 0825669995;
};
pResponseCode = {
text = 00;
};
pResponseMessage = {
text = Approved;
};
pTrx = {
cTrx = (
{
pCardHolderName = {
};
pReference = {
text = 140826121114;
};
pTransactionAccount = {
text = "364241****0016";
};
pTransactionDate = {
text = "8/26/2014 12:11:18 PM";
};
pTransactionID = {
text = 23;
};
},
{
"xsi:nil" = true;
}
);
};
};
};
};
};
}
Thanks.
You can access dictionary and array values with square brackets:
val = dictionary[#"key"];
item = array[i];
It works for nested dictionaries as well:
NSDictionary *nested = #{#"dict_key": dictionary};
dictionaryVal = nexted[#"dict_key"][#"key"];
So, in your case, you could access cTrx array in next way:
NSArray *cTrx = yourDictionary[#"Envelope"][#"Body"][#"fRetrieveTransactionsforReversalResponse"][#"pTrx"][#"cTrx"];
Long string of code :)

Comparing two version numbers

How can I compare two Version number strings?
For example: 3.1.1 and 3.1.2.5.4
Now I need to find out if 3.1.2.5.4 is higher than 3.1.1 but I don't know how to do this.
Can anybody help me?
Thanks in advance!
Sample Code :
NSString* v1 = #"3.1.1";
NSString* v2 = #"3.1.2.5.4";
if ([v1 compare:v2 options:NSNumericSearch] == NSOrderedDescending) {
NSLog(#"%# is greater than %#",v1,v2);
}
From the Apple Documentation for Comparing and sorting strings.
Yes, you can compare the versions, please refer the code below:
public class Comparision {
string ver1, ver2;
public static void main(String args[]){
string ver1Split[] = ver1.split('.');
string ver2Split[] = ver2.split('.');
for (int i = 0; i < ver1Split.length; ++i) {
if (ver2Split == i) {
return ver1 + " is larger";
}
if (ver1Split[i] == ver2Split[i]) {
continue;
}
else if (ver1Split[i] > ver1Split[i]) {
return ver1 + " is larger";
}
else {
return ver2 + " is larger";
}
if (ver1Split.length != ver2Split.length) {
return ver2 + " is larger";
}
return "versions are equal";
}
}
Objective-C:
- (BOOL)isVersion:(NSString *)arg1 higherThan:(NSString *)arg2 {
NSMutableString * v1 = arg1.mutableCopy;
NSMutableString * v2 = arg2.mutableCopy;
NSMutableArray * parts1 = [v1 componentsSeparatedByString:#"."].mutableCopy;
NSMutableArray * parts2 = [v2 componentsSeparatedByString:#"."].mutableCopy;
if (parts1.count > parts2.count) {
NSInteger diff = parts1.count - parts2.count;
for (NSInteger i = diff; i<parts1.count; i++) {
[v2 appendString:#".0"];
}
} else if (parts1.count < parts2.count){
NSInteger diff = parts2.count - parts1.count;
for (NSInteger i = diff; i<parts2.count; i++) {
[v1 appendString:#".0"];
}
}
parts1 = [v1 componentsSeparatedByString:#"."].mutableCopy;
parts2 = [v2 componentsSeparatedByString:#"."].mutableCopy;
NSInteger j = 0;
for (NSString * num1 in parts1) {
NSString * num2 = parts2[j];
if(num1.integerValue > num2.integerValue){
//break;
return YES;
} else if (num1.integerValue < num2.integerValue) {
//break;
return NO;
} else {
// ==
}
j++;
}
return NO;
}
Unit test:
- (void)test_isHigherFunc {
XCTAssert([self isVersion:#"4.1.2.1" higherThan:#"4.1.2.0"]);
XCTAssertFalse([self isVersion:#"4.1.2.0" higherThan:#"4.1.2.0"]);
XCTAssert([self isVersion:#"4.1.2.0" higherThan:#"4.1.1.0"]);
XCTAssertFalse([self isVersion:#"3.1.2.0" higherThan:#"4.1.1.0"]);
XCTAssertFalse([self isVersion:#"4.2.2.0" higherThan:#"4.3.1.0"]);
XCTAssert([self isVersion:#"5.2" higherThan:#"4.3.1.0"]);
XCTAssertFalse([self isVersion:#"6.2" higherThan:#"7.3.1.0"]);
XCTAssert([self isVersion:#"6.2" higherThan:#"5"]);
XCTAssert([self isVersion:#"6.2.0" higherThan:#"5.9"]);
XCTAssert([self isVersion:#"1.1.1.1.1.1.1.1" higherThan:#"1.1.1.1.1.1.1.0"]);
XCTAssert([self isVersion:#"2.0" higherThan:#"1"]);
}

Resources