kCGImagePropertyGIFLoopCount returns wrong value - objective-c

I have three GIF files which are loaded as NSData.
When I use the key kCGImagePropertyGIFLoopCount to retrieve the LoopCount, it returns a wrong value.
For the GIF which should loop infinitely, it returns 0 (correct).
For the GIF with Loop count 1, it returns 0 (incorrect).
For the GIF with Loop count 2, it returns 1 (incorrect).
-(void)prepareGif:(NSData*)data {
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef) data, NULL);
CFDictionaryRef properties = CGImageSourceCopyProperties(source, nil);
NSDictionary* imageProperties = (__bridge NSDictionary*) properties;
NSDictionary* gifProperty = imageProperties[(NSDictionary*) kCGImagePropertyGIFDictionary];
int loopCount = [gifProperty[(NSString*) kCGImagePropertyGIFLoopCount] intValue]; // returns 0 for LoopCount 1 and LoopCount 0 and returns 1 for LoopCount 2
Here are the three GIFs:
Someone know what I am doing wrong here or is it a bug?

I found the answer.
The property is absent when it doesnt loop (i.e. playback count = 1).
It was my mistake since the gifProperty dictionary returns objects and not primitive types. The returned object was a NSNumber, which was casted to int with a default value of 0. I didn't check for nil

Related

Comparison between pointer and int (id to int) - Object wrapping still doesn't work [duplicate]

So my problem is this:
I am receiving a JSON string from across the network. When decoded (using SBJSON libraries), it becomes an NSDictionary that SHOULD contain a number of some sort for the key 'userid'. I say 'should' because when I compare the value to an int, or an NSINTEGER, or NSNumber, it never evaluates correctly.
Here is the comparison in code:
NSDictionary *userDictionary = [userInfo objectAtIndex:indexPath.row];
if ([userDictionary objectForKey:#"userid"] == -1) {
//Do stuff
}
The value inside the dictionary I am testing with is -1. When I print it out to console using NSLog it even shows it is -1. Yet when I compare it to -1 in the 'if' statement, it evaluates to false when it should be true. I've even tried comparing to [NSNumber numberWithInt: -1], and it still evaluates to false.
What am I doing wrong? Thanks in advance for your help!
You are comparing a pointer to an object, not an integer itself. You must first convert the object into an integer:
if ([[userDictionary objectForKey:#"userid"] integerValue] == -1)
{
//Do stuff
}

Take a number from JSON and use it to setValue to Int 32 in Core Data

I have an array, pulled from JSON received from a web service. When I use NSLOG to view the contents of the array, it displays like this:
{ ? Category = "New Products";
CategoryID = 104;
SubCategories = (
);
}
I need to take the Category and CategoryID values and assign them to the managed object "newProductCategory". I have no problem assigning the Category value, which corresponds to a string type, and I have no problem assigning a hard-coded number to the int 32 type that's supposed to receive the Category ID. But I've been struggling when it comes to converting the CategoryID value into anything that will be accepted as the int 32 type.
What's the proper syntax for converting that value into something digestible for this line of code, in place of the zero?
[newProductCategory setValue : 0 forKey : #"productCategoryID"];
Here's one of my failed attempts that might be informative. When I try...
// Pull category record "i" from JSON
NSArray * categoryProperties = [categories objectAtIndex:i];
NSNumber * productCategoryID = [categoryProperties valueForKey:#"CategoryID"];
... then I attempt to assign it in the above format, using productCategoryID in place of the zero, it produces the following error:
'NSInvalidArgumentException', reason: 'Unacceptable type of value for attribute: property = "parentCategoryID"; desired type = NSNumber; given type = __NSCFString; value = 104.'
Even if you specify int32 in CoreData, you will pass a NSNumber object, and it seems that you get a NSString from the json parsing (you can try a log of NSStringFromClass([productCategoryID class]) to be sure).
You can try :
NSString * productCategoryID = [categoryProperties valueForKey:#"CategoryID"];
newProductCategory.productCategoryID = #([productCategoryID intValue]);
//or
newProductCategory.productCategoryID = [NSNumber numberWithInt:[productCategoryID intValue]];
You need to set NSNumber, there are 2 ways:
[newProductCategory setValue:#(0) forKey:#"productCategoryID"];
or
[newProductCategory setValue:[NSNumber numberWithInt:0] forKey:#"productCategoryID"];

Moving several objects in a NSMutableArray

Let's suppose I have a NSMutableArray like this:
Object 0
Object 1
Object 2
Object 3
Object 4
and would like to take Object 0 and Object 1 and move them behind Object 4:
Object 2
Object 3
Object 4
Object 0
Object 1
I have this rather long code to achieve the re-ordering of multiple objects, but I was wondering if there is a more straightforward / elegant way:
int from = 0;
int to = 5;
int lastIndexOfObjectsToBeMoved = 1;
NSMutableArray *objectsToBeMoved = [[NSMutableArray alloc] init];
for (int i = from; i < lastIndexOfObjectsToBeMoved; i++) {
object *o = [self.objects objectAtIndex:i];
[objectsToBeMoved addObject:o];
}
NSUInteger length = lastIndexOfObjectsToBeMoved-from;
NSRange indicesToBeDeleted = NSMakeRange(from, length);
[self.objects removeObjectsInRange:indicesToBeDeleted];
NSIndexSet *targetIndices = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(to, length)];
[self.objects insertObjects:objectsToBeMoved atIndexes:targetIndices];
Edit: sorry, I should have clarified, I'm not always moving objects to the very end, but would also like to be able to do things like moving object 2 and 3 to index 0.
Make an NSRange of the indexes you want to move to the back. Grab those objects with subarrayWithRange, remove them with removeObjectsInRange: and add them back to the end by calling addObjectsFromArray:. This is a much more concise way of writing what you have.
rowIndexes is a NSIndexSet with objects you like move
row is the index destination
NSArray *objectsToMove = [your_array objectsAtIndexes: rowIndexes];
// If any of the removed objects come before the row
// we want to decrement the row appropriately
row -= [rowIndexes countOfIndexesInRange: (NSRange){0, row}];
[your_array removeObjectsAtIndexes:rowIndexes];
[your_array replaceObjectsInRange: (NSRange){row, 0}
withObjectsFromArray: objectsToMove];
I hope this helps you

How to remove nil entries from NSMutableDictionary

I have a Mutable Dictionary that I removed an element from with removeObjectForKey. That's fine, but when I enumerate thru the Dictionary, there is a 'hole' for the element I deleted. So when I print the Dictionary, it displays that element as (null).
Is there way to 'pack' the dictionary after removing an element? I need contiguous numbers for the keys. Example:
BEFORE DELETE:
key:1 value:red
key:2 value:green
key:3 value:blue
key:4 value:yellow
myDictionary removeObjectForKey:2
CURRENT:
key:1 value:red
key:3 value:blue
key:4 value:yellow
DESIRED:
key:1 value:red
key:**2** value:blue
key:**3** value:yellow
Code to remove nil entry from NSMutableDictionary. This is what I came up with, but it is not working:
int count = dictFaves.count;
int x = 1; // Dictionaries are 1-relative
while ( x <= count ) {
// get the current row
NSString *curRow = [NSString stringWithFormat:#"%d", x];
NSString *temp = [dictFaves objectForKey:curRow];
// is this row empty? if so, we have found our hole to plug
if ( temp == nil ) {
// copy the Fave from the 'next' row to the 'current' row. Effectively
// shifting it 1 lower in the Dictionary
NSString *nextRow = [NSString stringWithFormat:#"%d", x + 1];
temp = [dictFaves objectForKey:nextRow];
[dictFaves setObject:temp forKey:[NSNumber numberWithInt:x]];
// one final thing to cleanup: remove the old 'next' row.
// It has been moved up 1 slot (along with all others)
[dictFaves removeObjectForKey:[NSString stringWithFormat:#"%d", x+1]];
}
x = x + 1;
}
That happens because the NSDictionary (and its mutable subclass) acts like a hash/map/associative array. If you want to keep the indices running consecutively, you have to either reset them after removing an object, or just store everything in a NSMutableArray.

Binary conversion algorithm in objective-c

How do I get the value of a certain bit from a byte or integer? The only similar answer that I've been able to find is for a specific character inside a string. I am trying to convert a binary number to a decimal number, and perhaps there is a much simpler way to do this, but I was thinking of this: multiplying 2^(position of integer from right) by either a 1 or 0, depending on the value of the integer at the position previously mentioned. Any tips?
NSString * binary = #"0011010";
long value = strtol([b UTF8String], NULL, 2);
There are multiways of obtaining the value of bit within a byte or integer. It all depends on your needs.
One way would be to use a mask with bitwise operators.
int result = sourceValue & 8; // 8 -> 0x00001000
// result non zero if the 4th bit from the right is ON.
You can also shift bits one by one and read, say, the right-most bit.
for (int i = 0; i < 8; i++)
NSLog(#"Bit %d is %#", i, (sourceValue % 2 == 0) ? #"OFF" : #"ON");
sourceValue = sourceValue >> 1; // shift bits to the right for next loop.
}
Or if you just want the text representation for an integer, you could let NSNumber do the work:
NSString* myString = [[NSNumber numberWithInt:sourceValue] stringValue];