iOS use ID3Lib to edit ID3 tags from mp3 files in the NSDocsDir - ios

I am using ID3Lib example project to edit Title, Album and Artist ID3 tags on mp3 files and all is good until I come to adding an image (cover Art) if any one has any ideas how to finish off the below code that would be great:
- (void)demo {
nImage = [UIImage imageNamed:#"amazing-grace.jpg"];//unused
NSString *imagePath = [[NSBundle mainBundle] pathForResource:#"amazing-grace" ofType:#"jpg"];
NSString *path = [[NSBundle mainBundle] pathForResource:#"amazing-grace-10s" ofType:#"mp3"];
NSArray *docPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath = [[docPaths objectAtIndex:0] stringByAppendingPathComponent:#"amazing-grace-10s.mp3"];
[[NSFileManager defaultManager] copyItemAtPath:path toPath:docPath error:nil];
// Read title tag
ID3_Tag tag;
tag.Link([path UTF8String]);
ID3_Frame *titleFrame = tag.Find(ID3FID_TITLE);
unicode_t const *value = titleFrame->GetField(ID3FN_TEXT)->GetRawUnicodeText();
NSString *title = [NSString stringWithCString:(char const *) value encoding:NSUnicodeStringEncoding];
NSLog(#"The title before is %#", title);
// Write title tag
tag.Link([docPath UTF8String]);
tag.Strip(ID3FID_TITLE);
tag.Strip(ID3FID_ALBUM);
tag.Strip(ID3FID_LEADARTIST);
tag.Clear();
ID3_Frame frame;
frame.SetID(ID3FID_TITLE);
frame.GetField(ID3FN_TEXTENC)->Set(ID3TE_UNICODE);
NSString *newTitle = nTitle;
frame.GetField(ID3FN_TEXT)->Set((unicode_t *) [newTitle cStringUsingEncoding:NSUTF16StringEncoding]);
ID3_Frame frame2;
frame2.SetID(ID3FID_ALBUM);
frame2.GetField(ID3FN_TEXTENC)->Set(ID3TE_UNICODE);
NSString *newAlbum = nAlbmum;
frame2.GetField(ID3FN_TEXT)->Set((unicode_t *) [newAlbum cStringUsingEncoding:NSUTF16StringEncoding]);
ID3_Frame frame3;
frame3.SetID(ID3FID_LEADARTIST);
frame3.GetField(ID3FN_TEXTENC)->Set(ID3TE_UNICODE);
NSString *newArtist = nArtist;
frame3.GetField(ID3FN_TEXT)->Set((unicode_t *) [newArtist cStringUsingEncoding:NSUTF16StringEncoding]);
//this is the image code
ID3_Frame frame4;
frame4.SetID(ID3FID_PICTURE);
frame4.GetField(ID3FN_TEXTENC)->Set(ID3TE_UNICODE);// dont think this should be TEXTENC
NSString *newImage = imagePath;
frame4.GetField(ID3FN_DATA)->FromFile((const char *)[newImage cStringUsingEncoding:NSUTF16StringEncoding]);//this line is also probably wrong
tag.AddFrame(frame);
tag.AddFrame(frame2);
tag.AddFrame(frame3);
tag.AddFrame(frame4);
tag.SetPadding(false);
tag.SetUnsync(false);
tag.Update(ID3TT_ID3V2);
NSLog(#"The title after is %# The album after is %# The artist after is %# The artist after is %#", newTitle,newAlbum,newArtist,newImage);
}

Use file path with UTF-8 encoding and will work fine:
frame.GetField(ID3FN_DATA)->FromFile((const char *)[newImage cStringUsingEncoding:NSUTF8StringEncoding]);

I get this code, From this source: https://android.googlesource.com/platform/external/id3lib/+/8a58cac9f8db5ed55b02b3ac24156d628af923d1/examples/test_pic.cpp
frame.SetID(ID3FID_PICTURE);
frame.GetField(ID3FN_MIMETYPE)->Set("image/jpeg");
frame.GetField(ID3FN_PICTURETYPE)->Set(11);
frame.GetField(ID3FN_DESCRIPTION)->Set("B/W picture of Saint-Saëns");
//frame.GetField(ID3FN_DATA)->FromFile("composer.jpg");
frame.GetField(ID3FN_DATA)->FromFile((const char *)[newImage cStringUsingEncoding:NSUTF8StringEncoding]);
tag.AddFrame(frame);
And! this work nice. :D

Related

iOS11.2 NSFileManager API behivour is different than previous iOS versions

I am using below piece of code to calculate a checksum for files I added in a "temp" folder for app bundle. I am getting different checksum values in iOS11.2 compared to all lower iOS version. I was wondering what has changed among these versions? Is some changes in File system in iOS 11.2 is reason for the difference? Can somebody please throw light on the issue or faced similar issues? Below is the piece of code I used.
NSString* bundleRootDir;
bundleRootDir = [[NSBundle mainBundle] bundlePath];
NSLog(#"bundleRootDir %# ",bundleRootDir );
NSString *tmpDir = [bundleRootDir stringByAppendingPathComponent:#"temp"];
NSLog(#"tmpDir %# ",tmpDir);
NSFileManager *fileManager1=[[NSFileManager alloc] init];
NSDirectoryEnumerator *dirEnum = [fileManager1 enumeratorAtPath:tmpDir];
// NSFileManager *fileManager1 = [NSFileManager defaultManager];
//NSArray *filePathsArray1 = [fileManager1 subpathsOfDirectoryAtPath:tmpDir error:nil];
NSMutableData *allFilesData1 = [NSMutableData new];
uLong crc1 = crc32(0L, Z_NULL, 0);
NSInteger filecount1=0;
//for (NSString *file1 in filePathsArray1) {
NSString *file1;
while ((file1 = [dirEnum nextObject])) {
NSString *fullPathToFile1 = [tmpDir stringByAppendingPathComponent:file1];
BOOL isDirectory1;
if ([fileManager1 fileExistsAtPath:fullPathToFile1 isDirectory:&isDirectory1] && isDirectory1 ) {
// ignore directories...
continue;
}
else {
NSData *myData1 = [NSData dataWithContentsOfFile:fullPathToFile1];
[allFilesData1 appendData:myData1];
NSLog(#"Checksum files included %# , %d",fullPathToFile1,filecount1);
}
filecount1++;
}
NSLog(#"Checksum cal : length of data %lu",[allFilesData1 length]);
NSString *strData = [[NSString alloc]initWithData:allFilesData1 encoding:NSUTF8StringEncoding];
NSLog(#"All Data for checksum %#",strData);
crc1 = crc32(crc, [allFilesData1 bytes], [allFilesData1 length]);
NSLog(#"WL_INIT_PACKAGE - testWebResourcesChecksum crc32 output %lu",crc1);
NSString *checksum1 = [NSString stringWithFormat:#"%lu", crc1];
NSLog(#"WL_INIT_PACKAGE - testWebResourcesChecksum crc32 output %#",checksum1);

How to know index of current Object with name

I have an array called poemcollection
poemcollection = [[NSMutableArray alloc] initWithObjects:
[[NSBundle mainBundle] pathForResource:#"twinkle_twinkle" ofType:#"mp3"],
[[NSBundle mainBundle] pathForResource:#"baa_baa_black_sheep" ofType:#"mp3"],
[[NSBundle mainBundle] pathForResource:#"johny_johny" ofType:#"mp3"],
on button click
I want to know which object is playing currently from this array and index of this object.
I want to print in log this both name and index of current file playing on player
[poemcollection indexOfObject:YOUR_CURRENT_PLAYING_OBJECT];
Something like this?
-(void)printCurrentlyPlaying
{
NSString *mediaFileName = [[self.player.url absoluteString] lastPathComponent];
BOOL found = NO;
int poemIndex = -1;
for(int i = 0; i < poemcollection.count && !found; i++)
{
NSString *filePath = poemcollection[i];
NSString *fileName = [filePath lastPathComponent];
if([fileName isEqualToString:mediaFileName])
{
found = YES;
poemIndex = i;
}
}
if(found)
{
NSLog(#"Currently playing: %#, track number: %d", mediaFileName, poemIndex);
}
}
You can keep a mapping dictionary for the media name, e.g -
poemCollection = #[ #{"Twinkle twinkle": [[NSMutableArray alloc] initWithObjects:
[[NSBundle mainBundle] pathForResource:#"twinkle_twinkle" ofType:#"mp3"]},
#{#"Baa baa black sheep": [[NSBundle mainBundle] pathForResource:#"baa_baa_black_sheep" ofType:#"mp3"]},
#{"Johny Johny": [[NSBundle mainBundle] pathForResource:#"johny_johny" ofType:#"mp3"]}];
//And read the title like below :
NSString *title = [poemCollection[index] allKeys][0]
NSString *musicFile = [poemCollection[index] allValues][0]
try this code to get current file name and object.
NSString *currentFile = [[self.player.url absoluteString] lastPathComponent];
[poemcollection indexOfObject:currentFile];

How to read a text file ,turn it into a string, then using arguments on it

Say If I had a string = "There were %# apples,I ate %#. Now I have %# apples" in text file "Apples.txt". This is how I will extract the text from it.
NSString *path = [[NSBundle mainBundle] pathForResource:#"Apples" ofType:#"txt"];
NSString *content = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
Now how do I pass the arguments to it so it looks like this:
"There were %# apples,I ate %#. Now I have %# apples", x, y, x-y
I am sure there is a way around this using NString with arguments? using
NSString with local argument functions? otherwise I will have to type all of my text in the file.m
This very crucial for my app.
You are probably looking for [NSString stringWithFormat:...].
Your complete code goes like this :
NSString *path = [[NSBundle mainBundle] pathForResource:#"Apples" ofType:#"txt"];
NSString *content = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
NSNumber *total = #100;
NSNumber *ate = #34;
NSString *fullString = [NSString stringWithFormat:content,total,ate, #([total integerValue] - [ate integerValue])];
NSLog(#"%#", fullString);
Output:
"There were 100 apples,I ate 34. Now I have 66 apples".
Use + stringWithFormat:
Here's the Apple reference

NSTask not working for file path with special characters

I am using NStask to get the folder size.Its working fine for normal file paths like home/ABC/Users/testUser/Documents. But it is not showing any output for file path like home/ABC/Users/testUser/Ω≈ç∂√√√∂ƒ∂.However I am getting proper output for the same file path on terminal. Any suggestion?
NSString* userName = #"test123_test123";
NSString* password = #"test";
NSString* serverIP = #"200.144.172.210";
NSString* sizeFolderPath = [[NSBundle mainBundle] pathForResource:#"demoUtilities" ofType:nil];
NSString* xml= #"--test";
NSString* passwordArg = [NSString stringWithFormat:#"--pwd-=%#",password];
NSString *filePath = #"UsersMac/Users/test/Ω≈ç∂√√√∂ƒ∂";
NSString* address = [NSString stringWithFormat:#"%##%#::home/%#", userName, serverIP,filePath];
NSArray* arguments = [NSMutableArray arrayWithObjects:xml,passwordArg,address,nil];
TestCommandExcecuter *cmExec = [[TestCommandExcecuter alloc]init];
[cmExec setCommandString:sizeFolderPath];
[cmExec setCommandArguments:arguments];
I am using this code:
Depricated from 2.0
NSDictionary *fileDictionary = [[NSFileManager defaultManager]
fileAttributesAtPath:filePath traverseLink:YES];
long long size = [fileDictionary fileSize];
NSLog(#"size :: %lld",size);
Latest :
NSDictionary *fileDictionary = [[NSFileManager defaultManager]
attributesOfItemAtPath:filePath error:nil];
long long size = [fileDictionary fileSize];
NSLog(#"size :: %lld",size);
Here is the reference link :
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/Reference/Reference.html#//apple_ref/occ/instm/NSFileManager/attributesOfItemAtPath%3aerror%3a

Data in csv file after export

I have a problem with data who are exported to a csv file.
It concerns the data with accented characters. Type Data is string.
in my file i have this :
Téléphones et internet; Abonnement iPad; 13,90 €; Débit
I would like to have :
Téléphones et internet; Abonnement iPad; 13,90€ Débit
what code should be used to do this?
Thank you.
EDIT : my code
NSMutableString *writeString = [NSMutableString string];
for (id object in [[self fetchedResultsController] fetchedObjects]) {
NSString * object1 = [[object valueForKey:#"object1Data"] description];
NSString * object2 = [[object valueForKey:#"object2Data"] description];
NSString * object3 = [[object valueForKey:#"object3Data"] description];
NSString * object4 = [[object valueForKey:#"object4Data"] description];;
[writeString appendString:[NSString stringWithFormat:#"%#; %#; %#; %#\n", object1, object2, object3, object4]];
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* savePath = [paths objectAtIndex:0];
savePath = [savePath stringByAppendingPathComponent:#"objectData.csv"];
[writeString writeToFile:savePath atomically:YES encoding:NSUTF8StringEncoding error:NULL];
EDIT2 : for viewing i use his :
QLPreviewController *previewController=[[QLPreviewController alloc]init];
previewController.delegate=self;
previewController.dataSource=self;
[self presentViewController:previewController animated:YES completion:nil];
[previewController.navigationItem setRightBarButtonItem:nil];
- (id <QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* savePath = [paths objectAtIndex:0];
savePath = [savePath stringByAppendingPathComponent:#"objectData.csv"];
return [NSURL fileURLWithPath:savePath];
}
- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller
{
return 1;
}
Your output looks like it might be correct, the problem seems like it’s in how you are viewing it.
Are you importing it into Excel or something? Excel’s CSV import is very poor in my experience, and it won’t auto-detect incoming UTF-8 data.
It's likely the encoding that's causing an issue here.
As a side note it's a CSV = Comma Separated Values. You aren't putting the commas in .. ?
Change:
[writeString appendString:[NSString stringWithFormat:#"%#; %#; %#; %#\n", object1, object2, object3, object4]];
To:
[writeString appendString:[NSString stringWithFormat:#"%#;, %#;, %#;, %#\n", object1, object2, object3, object4]];
This will make the values appear in separate columns when opened in excel, unless you want it all in 1 column ... ?

Resources