NSMutableArray storing integers - objective-c

I know this is probably basic... I’m trying to store an answer to a multiple choice question (i.e. integer 1-4) stored in “selection”. The question number is “gCount”. This prints nil for the answerSubmit array. What part is wrong? Thanks...
[answerSubmit insertObject:[NSNumber numberWithInt:selection] atIndex:gCount];
NSLog(#"Answer submit: %#\n",[answerSubmit objectAtIndex:gCount]);

If you have those two statements, exactly as shown, back-to-back in your program, and if the printed result was "Answer submit: (nil)", then "answerSubmit" is nil going in.

Related

MCNearbyServiceAdvertiser Multi-Object DiscoveryInfo

I do not understand how this makes sense. I put two objects in the discoveryinfo dictionary inside the MCNearbyServiceAdvertiser object that I create and the browser doesn't see the advertiser, yet when I move the second object out of the dictionary and comment it out at the end of the line, the browser sees the advertiser. Does the discoveryinfo dictionary only accept one object to work? I have a string as the first object and an array as the second. Here is what it looks like:
advertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:myPeerID discoveryInfo:#{#"Name": [[NSString alloc] initWithString:myUniqueID], #"Peers": [[NSArray alloc] initWithArray:connectedPeersAry]} serviceType:#"Blahblah"];
And before that line, I tried this simpler format (but went to the above just in case the syntax was the problem):
advertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:myPeerID discoveryInfo:#{#"Name": myUniqueID, #"Peers": connectedPeersAry} serviceType:#"FRCSCOUT"];
I guess I can put a dictionary or array inside the discoveryinfo dictionary, but I feel it's a pretty dumb way of doing things because a dictionary shouldn't ever be limited to one object for any case.
I'll go ahead and put my objects in another layer to "conserve space" inside the discoveryinfo dictionary, but if any of you find a better way of doing things or if you are seeing the same problem, please let me know.
You can have multiple objects in the discoveryInfo dictionary, but keep in mind that the dictionary will be encoded in a Bonjour TXT record. This imposes a few restrictions on what can be put into that dictionary.
As stated in the documentation for [MCNearbyServiceAdvertiser initWithPeer:discoveryInfo:serviceType:]:
This data is advertised using a Bonjour TXT record, encoded according to RFC 6763 (section 6). As a result:
The key-value pair must be no longer than 255 bytes (total) when encoded in UTF-8 format with an equals sign (=) between the key and the value.
Keys cannot contain an equals sign.
For optimal performance, the total size of the keys and values in this dictionary should be no more than about 400 bytes so that the entire advertisement can fit within a single Bluetooth data packet.
Well, found my problem. As quoted by Apple in their class reference for MCNearbyServiceAdvertiser:
"The content of discoveryInfo will be advertised within Bonjour TXT records, so you should keep the dictionary small for better discovery performance."
So, looks like I'll have to use a comma separated string of some sort...
EDIT
I misunderstood the Multipeer Connectivity API. I thought the roles were reversed and the Advertiser was basically the public host for a Multipeer Session, but it should be the Browser that invites Advertisers. I now just have the Unique ID generated as the discovery info.
Thank you all for your help and sorry for the API confusion on my part.

Change value of multidimensional array in objective c?

I am having the strangest problem and looking for help. I have an array of arrays of integers. I am trying to change these values and I cannot find out how. Here is what I tried:
[[multidim-array objectAtIndex:0] replaceObjectAtIndex:0 withObject:[NSNumber numberWithInt:1]];
what this does is get the first array from the main array and change the integer at the first index to one. Or at least, that's what I think it should be doing. and its what the other threads here said it should do. But I am getting strange behavior.
The above code, for some reason, changes the first value of EVERY array to 1. It's as if I run the code 10 times on every array in the multidim-array array.
Anyone know why this could be happening? If my phrasing was unclear, what I am trying to do is the objective-c equivelant of multidim-array[0][0] = 1;
EDIT: Someone told me this should work so here is info about how I am handling the array. The array starts out filled with 0s. There is a lot of code affecting the array but it shouldn't matter because I have breakpoints trailing through so I can see what each line of code does to the array. Before I run that line, the numbers are all 0s. I try and change one value, and they a whole bunch of them become changed. I am still looking into it if no one knows what's happening :/
I'm guessing that you've assigned the same inner array to every element of the outer array.
BTW, you can actually write this:
multidim_array[0][0] = #1;

NSString isEqual strange bug

I have a web server which I used to fetch some data in my iOS application. The data include a field as the itemId let say '48501' (with no quotation). I read item JSON data into my itemObject in which itemId is defined as a NSString and not a NSInteger.
Everything works until this point but I have problems where I want to compare itemObject.itemId using isEqual: function with another NSString filled with 48501.
In other words both string are exactly the same and include 48501 when I print them. No space and hidden things is there. All isEqual: and isEqualToString: and == report false on comparison.
On the hand when I convert NSStrings to NSIntegers and compare them it works but not always! sometime TRUE sometime CRASH with no error to catch and just pointing to the line! I see them printed exactly the same but the if statement does not go through.
I showed the code to someone with far more experience than me and he was like this could be a bug! Anyone has ever exposed to this?
If your itemId is 48501 without any quotation in the JSON, then it's deserialized as NSNumber. Probably that's the problem in the first place. Try logging the type of your itemId and use appropriately -isEqualToString: for NSString and -isEqualToNumber: for NSNumber.

Objective-C: how to compare 2 PLists

I'm a total newbie to Objective-C and have been tasked with an assignment to compare 2 builds of same app for differences in their Info.plist and Defaults.plist.
I have been able to figure out the steps to read the PLists from app bundle but am having difficulty figuring out how to compare EVERY key in PLists to its counterpart file. For illustration if I need to compare Info.plist between 2 app bundle (lets say build_100 and build_101), how do I recursively go to each key in build_100 and compare the same key in build_101 to verify if they are same or not.
Its easy if both PLists are same because isEqualToDictionary will return TRUE but problem occurs if something in a nested dictionary is different between both the builds.
Going through related queries here, it clear to me that the answer is that I write a recursive method that iterates through both PLists but I'm having a real frustrating time to figure out a way to do this for a nested dictionary like Info.plist.
So I've finally figured this thing out so thought of sharing it with others for future reference. I'm sure there'll be some other lost soul in future looking for something similar (or at least I hope :)).
The way I wrote my code was to:
Read both Plists in NSDictionaries
Treat one Plist as "to be tested" and other as the reference (to compare against) to find out if its a Pass/Fail
Loop through all keys in "to be tested" Plist and compare each one of them in "reference" Plist
When it came to compare an Array or Dictionary, this check (that's the part I was struggling with) had to be a recursive check
The code to write for step #1, 2, 3 is straight forward so I'm going to give the method I wrote for #4 which was the crux of my original question.
This function compareSourceObject() will take 3 arguments:
sourceObject: object to be tested
targetObject: object to compare against
trailPath: string that'll hold the entire path of the key that has failed
- (void)compareSourceObject:(id)sourceObject andTargetObject:(id)targetObject withBreadcrumbTrail:(NSString *)trailPath{
NSString *message = [[NSString alloc] init];
if ([sourceObject isKindOfClass:[NSDictionary class]]){
for(id item in sourceObject){
[self compareSourceObject:[sourceObject objectForKey:item] andTargetObject:[targetObject objectForKey:item] withBreadcrumbTrail:[trailPath stringByAppendingFormat:#"->%#", item]];
}
}
else if ([sourceObject isKindOfClass:[NSArray class]]){
for (int counter=0; counter %d", counter]];
}
}
else if(![sourceObject isEqual:targetObject]){
NSLog(#"Values do not match. Value in \"TestedDicationary\" is (%#) but the reference dict has (%#)", targetObject, sourceObject);
}
}
Hope this helps. Comments/Suggestions/Optimizations are more than welcome.
Take one plist, and interpret the properties as a set (NSSet) of string values, e.g.
:items:0:assets array
:items:0:assets:0:kind string VALUE
Note I am using /usr/libexec/PlistBuddy format to describe a property - path type [value].
Then do the same for the second plist and compare the sets using NSSet functions.

Comparing two NSManagedObjects

I have some code that loops through an array of NSManagedObjects and stops when it finds a certain record that is stored in an instance variable. The only way I can manage to see if they are the same record (not an equivalent record, the specific record) is by comparing the URIRepresentations of the objectIDs. This surely cannot be the best way of doing it. I'm doing:
if ([[[obj1 objectID] URIRepresentation] isEqualTo: [[_obj2 objectID] URIRepresentation]]) {
NSLog(#"Match");
}
The following code never matches even when I NSLog the objectIDs and see that they are in fact exactly the same.
if ([[obj1 objectID] isEqualTo: [_obj2 objectID]]) {
NSLog(#"Match");
}
The commenter is correct, isEqualTo: will not work in this case since they are different instances of NSManagedObjectID.
The way you are doing this is actually the best way, the objectID is CoreData's unique identifier for a given managed object, it's the only way to tell if two instances of NSManagedObject point to the same record in the persistent store.
Clarification:
ImHuntingWabbits refers to isEqual:, but then advises Nick to stick with his first example, which actually uses isEqualTo:.
Per Peter Hosey's comment to the post isEqual vs isEqualTo, there is a difference and you're better off using isEqual:.
Following the present posts, I originally used isEqualTo: to compare objectID URLs, which worked fine in Cocoa, but when I moved this code over to iOS, I got warnings that "NSURL may not respond to isEqualTo." When I changed to isEqual:, the warnings went away.
So if you're following these examples, you should probably do this:
if ([[[obj1 objectID] URIRepresentation] isEqual:[[_obj2 objectID] URIRepresentation]] {
NSLog(#"Match");
}
-isEqual: has been implemented correctly for NSManagedObjectID in CoreData. We use collections with -contains: all the time. It seems that the original poster confused -isEqual: with -isEqualTo: The latter should not be used.