How can I extract exif data from a THM file in iOS? - ios

I'm trying to view the media track creation date in the exif data of a THM file. Using the command line utility exiftool, I am able to see this property. How can I see it using objective c?
This is what I've tried so far.
[self downloadImageWithURL:[candidateVideo objectForKey:#"thmURL"] completionBlock:^(BOOL succeeded, NSData *data) {
if (succeeded) {
CGImageSourceRef source=CGImageSourceCreateWithData((__bridge CFDataRef)data,NULL);
NSDictionary* metaData=(__bridge NSDictionary*)CGImageSourceCopyPropertiesAtIndex(source,0,NULL);
NSMutableDictionary* metaDataMutable=[metaData mutableCopy];
//recalculate validity with the images exif data
NSMutableDictionary *EXIFDictionary = [[metaDataMutable objectForKey:(NSString *)kCGImagePropertyExifDictionary]mutableCopy];
NSLog(#"wut");
}
}];
But my EXIFDictionary is nil.
I've also tried this and my dictionary has some key value pairs but there are only 3 and they are not what I need. I've tried using UIIMageJPEGRepresenation() and UIImagePNGRepresentation() to no avail. Too bad there is no UIImageTHMRepresentation()...
[self downloadImageWithURL:[candidateVideo objectForKey:#"thmURL"] completionBlock:^(BOOL succeeded, NSData *data) {
if (succeeded) {
UIImage* thumbnail = [[UIImage alloc] initWithData:data];
NSData* pngData=UIImageJPEGRepresentation(thumbnail,1.0);
CGImageSourceRef source=CGImageSourceCreateWithData((__bridge CFDataRef)pngData,NULL);
NSDictionary* metaData=(__bridge NSDictionary*)CGImageSourceCopyPropertiesAtIndex(source,0,NULL);
NSMutableDictionary* metaDataMutable=[metaData mutableCopy];
//recalculate validity with the images exif data
NSMutableDictionary *EXIFDictionary = [[metaDataMutable objectForKey:(NSString *)kCGImagePropertyExifDictionary]mutableCopy];
NSLog(#"wut");
}
}];

Related

IOS - VCard Data not attaching properly

I'm trying to convert Vcard/vcf information in the form of JSON to an NSData object. When I try to attach the NSData object, it's not displaying properly. Am I missing a conversion step between the JSON information and the NSData object?
if(args[#"attachments"][#"vcf"]){
NSArray *vCard = [RCTConvert NSArray:args[#"attachments"][#"vcf"]];
NSLog(#"%#", vCard);
NSError *error = nil;
NSData *data = [NSJSONSerialization dataWithJSONObject:vCard options:kNilOptions error:&error];
NSLog(#"%#", data);
NSString *contactIdentifier = #"kUTTypeVCard";
NSString *contactName = [RCTConvert NSString:args[#"attachments"][#"contactName"]];
[ mcvc addAttachmentData:data typeIdentifier:contactIdentifier filename:contactName];
}
Here is the JSON Object being passed into the state:
data: "BEGIN:VCARD↵VERSION:4.0↵FN:Matthew Marks↵EMAIL;TYP…quot;];PREF=1:Matthewmarks13#gmail.com↵END:VCARD↵"
This is the NSLog of the data:
<5b224245 47494e3a 56434152 445c6e56 45525349 4f4e3a34 2e305c6e 464e3a4d 61747468 6577204d 61726b73 5c6e454d 41494c3b 54595045 3d5b2671 756f743b 776f726b 2671756f 743b2c20 2671756f 743b696e 7465726e 65742671 756f743b 5d3b5052 45463d31 3a4d6174 74686577 6d61726b 73313340 676d6169 6c2e636f 6d5c6e45 4e443a56 43415244 5c6e225d>

Compare two plist files or two NSDictionary in iOS

I have downloaded a plist file from server, that contains key value pair. Once app resumes/restarts then again I have to download file and check if file has changed.
below is the code to download... I am storing the key values in NSDictionary.
task1 = [session dataTaskWithURL:[NSURL URLWithString:[S3_SERVER_URL stringByAppendingString:propFile]] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
propfilePath = [documentsDirectory stringByAppendingString:propFile];
NSLog(#"DestPath : %#", propfilePath);
[receivedData appendData:data];
NSLog(#"Succeeded! Received %lu bytes of data",(unsigned long)[data length]);
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[data writeToFile:propfilePath atomically:YES];
if(error == nil){
plistDictionary = [[NSDictionary dictionaryWithContentsOfFile:propfilePath] retain];
[task2 resume];
} else {
}
}];
How can i compare the contents of the two plist files or NS dictionary?
Which function is best suited to do the above As I have to do this on app create/resume/restart?
It should be compatible to both ios7 and ios8 SDK.
If you want all changed key follow this:- This will return array of all changed keys.
Create a category for NSDictionary
NSDictionary+newDict.h
#import <Foundation/Foundation.h>
#interface NSDictionary (newDict)
- (NSArray*)changedKeysIn:(NSDictionary*)d;
#end
NSDictionary+newDict.m
#import "NSDictionary+newDict.h"
#implementation NSDictionary (newDict)
- (NSArray*)changedKeysIn:(NSDictionary*)d {
NSMutableArray *changedKs = [NSMutableArray array];
for(id k in self) {
if(![[self objectForKey:k] isEqual:[d objectForKey:k]])
[changedKs addObject:k];
}
return changedKs;
}
#end
Calling:-
#import "NSDictionary+newDict.h"
and:-
NSArray *keys = [dict1 changedKeysIn:dict2];
NSLog(#"%#", keys);
You could use the isEqualToDictionary: method from the NSDictionary class.
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/index.html#//apple_ref/occ/instm/NSDictionary/isEqualToDictionary:

Iterating an NSMutableDictionary with UIImage not working

I am trying to add Images fetched from an external service to an NSMutableDictionary and seeing weird results. This is what I am doing:
- (void)fetchImages{
//Fetch Item Brand Images
//self.itemBrands is an NSArray of NSDictionaries
for (NSDictionary *itemBrand in self.itemBrands){
NSString *currentItemId = [itemBrand objectForKey:#"ITEM_ID"];
//Valid Item Id. This Log message is displayed
NSLog(#"Current Item Id: %#",currentItemId);
NSString *currentItemImageUrl = [[IMAGE_URL stringByAppendingString:currentItemId] stringByAppendingString:#".png"];
//Image URL is valid. This log message is displayed
NSLog(#"Current Image URL: %#",currentItemImageUrl);
NSURL *url = [NSURL URLWithString:currentItemImageUrl];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
if (image == nil){
//This log message is displayed when image is not present
NSLog(#"Image not Present 1");
}else{
//This log message is displayed when image is present
NSLog(#"Image Present 1");
[self.itemBrandImages setObject:image forKey:currentItemId];
}
}
//This for loop is not being executed at all. No log messages displayed.
for(id key in self.itemBrandImages){
NSLog(#"Current Item Id2: %#",key);
if ([self.itemBrandImages objectForKey:key] == nil){
NSLog(#"Image Not Present 2");
}else{
NSLog(#"Image Present 2");
}
}
}
The 2nd for loop where I am iterating over self.itemBrandImages is not being executed at all. None of the log messages inside are being displayed.
I tried the following before posting my issue here:
1) Researched similar problems in stack overflow and incorporated suggestion from one of them. The suggestion was "Perform an alloc init of the NSMUtableDictionary" in the init method of the .m file. This didn't help either.
2) To isolate the issue, I even tried adding a simple string to the NSMUtableDictionary instead of the image but even that does not seem to retained.
I am really confused as as to what I am missing or doing wrong here. Inputs are really appreciated.
Thanks,
Mike G
Perhaps:
for(NSString *key in [self.itemBrandImages allKeys])
I did an alloc init of the NSMutableDictianary right in my fetchImages method and it worked! Not sure why the alloc init in the init method did not work.
So here are my takeaways from this issue:
1) If you have an Array or dictionary #property that you are just getting and setting and not really adding or deleting objects to, then you don't need to explicitly alloc init them.
2) If you have an Array or dictionary #property that you are adding or deleting objects to ,you need to explicitly alloc init them.
Are my above statements true? Would love to hear your inputs on this.
Thanks,
Mike
New code:
- (void)fetchImages{
//Fetch Item Brand Images
self.itemBrandImages = [[NSMutableDictionary alloc] init];
for (NSDictionary *itemBrand in self.itemBrands){
NSString *currentItemId = [itemBrand objectForKey:#"ITEM_ID"];
NSLog(#"Current Item Id in ItemList: %#",currentItemId);
NSString *currentItemImageUrl = [[#"http://anythingtogo.freeiz.com/images/"stringByAppendingString:currentItemId] stringByAppendingString:#".png"];
NSLog(#"Current Image URL in ItemList: %#",currentItemImageUrl);
NSURL *url = [NSURL URLWithString:currentItemImageUrl];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
if (image == nil){
NSLog(#"Image not Present 1");
}else{
NSLog(#"Image Present 1");
[self.itemBrandImages setObject:#"Test" forKey:currentItemId];
}
}

Write JSON from textfields to a file for iOS 5+

I'm new to iOS programming, and having trouble finding a beginner-level explanation of how to write the contents of multiple text fields to a local json file in such a way to keep everything organized.
For example, a user form would have Name, Address, Email, etc., which would need to be put into a Customer object.
The purpose of this is to save data from several forms, and eventually pass that data to a database.
You'll need to convert your text fields into a dictionary (or dictionary of dictionaries). Once you have that done, you convert the dictionary into JSON data and save that:
NSError *error = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:myJSONDict options:0 error:&error];
if (jsonData != nil) {
NSString *jsonFilePath = ...;
BOOL status = [jsonData writeToFile:jsonFilePath atomically:YES];
if (!status) {
NSLog(#"Oh no!");
}
} else {
NSLog(#"My JSON wasn't valid: %#", error);
}
You just need to create the path and check the status.
NSMutableDictionary* dict = [NSMutableDictionary dictionary];
[dict setObject:form.name.text forKey:#"name"]'
[dict setObject:form.address.text forKey:#"address"];
...
NSString* jsonString = [yourFavoriteJsonTool convertToJson:dict];

Add an NSDictionary to image metadata

I'm trying to save an image with some custom metadata to a Photo Album. The custom metadata I would like to save should be in the form of a NSDictionary. Until now I have only succeeded in inserting an NSArray into the image metadata by using something like below:
NSMutableDictionary *metadata = [[NSMutableDictionary alloc] init];
[metadata setObject:#[#"ele1", #"ele2"] forKey:(NSString*)kCGImagePropertyIPTCKeywords];
NSMutableDictionary *meta = [[NSMutableDictionary alloc] init];
[meta setObject:metadata forKey:(NSString*)kCGImagePropertyIPTCDictionary];
// pass the meta dictionary into writeImageDataToSavedPhotosAlbum
But what I would like is to pass a dictionary into setObject.
Has anyone succeeded in inserting a custom metadata into an image where the metadata is an NSDIctionary?
Additional information
I'm using the code I found here Save CUSTOM metadata in an image taken from AVFoundation in iOS, to add a dictionary to the image metadata but still no luck. The original file is in the temporary directory and the final file is created via writeImageDataToSavedPhotosAlbum. Like in the link, the resulting image doesn't contain the dictionary. Any idea?
CGImageSourceRef source = CGImageSourceCreateWithData((CFMutableDataRef)data, NULL);
NSDictionary *metadata = [(NSDictionary *) CGImageSourceCopyPropertiesAtIndex(source,0,NULL)autorelease];
NSMutableDictionary *metadataAsMutable = [metadata mutableCopy];
NSMutableDictionary *RAWDictionary = [[metadataAsMutable objectForKey:(NSString *)kCGImagePropertyRawDictionary]mutableCopy];
if(!RAWDictionary) {
RAWDictionary = [NSMutableDictionary dictionary];
}
[RAWDictionary setValue:#"value1" forKey:#"key1"];
[RAWDictionary setValue:#"value2" forKey:#"key2"];
[metadataAsMutable setObject:RAWDictionary forKey:(NSString *)kCGImagePropertyRawDictionary];
NSMutableData *newData = [NSMutableData data];
CFStringRef UTI = CGImageSourceGetType(source);
CGImageDestinationRef destination = CGImageDestinationCreateWithData((CFMutableDataRef)newData, UTI, 1, NULL);
if(!destination) {
NSLog(#"***Could not create image destination ***");
}
CGImageDestinationAddImageFromSource(destination,source,0, (CFDictionaryRef)metadataAsMutable);
BOOL success = NO;
success = CGImageDestinationFinalize(destination);
if(!success) {
NSLog(#"***Could not create data from image destination ***");
}
Try this :
//covert image to nsdata format
NSData *imageData = [[NSData alloc]initWithContentsOfFile:#"your image path"];
NSMutableDictionary *metadata = [[NSMutableDictionary alloc] init];
[metadata setObject:imageData forKey:#"imageData"];

Resources