Last summer, a terrible thing happened ... I covered the screw in my MacBook. All important data was easily recovered. Glory to the Time Machine! But the music collection, which I painstakingly cultivated over the years, was not lucky. It’s not a problem to restore the music itself, but the ratings and the number of plays whose history goes back to the very appearance of
iTunes under Windows, oh, what a pity. She experienced a lot of music library, including the transfer from Windows to Hakintosh, and then to MacBook.
The blessing of the midiatek was not all lost - there were only horns and legs, or rather the cherished file "
iTunes Librar y". The other day I decided to reanimate it.
Mac OS Solution

The obvious solution is to use
AppleScript . With it, almost any application in Mac OS can be automated. The language is so close to English and far from other programming languages that it put me in a stupor. I did not know which side to approach him.
I had to use XCode and some familiar
Objective-C . Working with XML caused almost no problems. NSXML ... and MSXML turned out to be a very similar API, not just the name.
')
With iTunes, things are more complicated. In addition to AppleScript itself, which can be used in Xcode projects, I found only two ways. Both are essentially wrappers for AppleScript.
1.
AppScript FrameworkOpen Source project from third-party developers. Suitable for Mac OS X since
10.3.9 . Supports
Objective-C ,
Ruby and
Python . The syntax seemed complicated, and I didn’t manage to compile it correctly, so I didn’t understand it.
2.
Scripting Bridge FrameworkApple’s own
proprietary solution, which was released only in Mac OS
10.5 . As the name implies, Scripting Bridge dynamically implements a bridge between Objective-C and applications with AppleScript support. This generates Objective-C classes based on the description of the script interface. They include objects and methods representing properties, elements, commands, and so on. "
On the second option, I stopped.
The first thing to do is add /System/Library/Frameworks/ScriptingBridge.framework to the project. Then create a special header file to know how to access an ActionScript-enabled application.
This is done by a command in the terminal:
sdef /Applications/iTunes.app | sdp -fh --basename iTunes
The file iTunes.h appears in the current folder, which you need to add to the Xcode project and you can access iTunes.
Similarly, you can do with any application that supports AppleScript.
Communication example
For example, the code that stores the list of songs, rating and number of performances:
- ( void ) ExportLibrary
{
Boolean shouldExportTrack = NO;
// iTunes
iTunesApplication *iTunes = [SBApplication applicationWithBundleIdentifier: @"com.apple.iTunes" ];
// iTunes ( , )
iTunesLibraryPlaylist *library = [[[[iTunes sources] objectAtIndex:0] playlists] objectAtIndex:0];
iTunesTrack *track;
// XML
NSXMLDocument *xmlNew = [[NSXMLDocument alloc] initWithXMLString: @"<?xml version=\"1.0\"?><LIBRARY/>" options:0 error:NULL];
NSXMLElement *rootNode = [xmlNew rootElement], *curNode;
//
NSInteger curLibTrack = 0, nLibTracks = [[library tracks] count];
NSLog( @"%i" , nLibTracks);
//
for (curLibTrack = 0; curLibTrack < nLibTracks; curLibTrack++)
{
track = [[library tracks] objectAtIndex:curLibTrack];
shouldExportTrack = (track.rating > 0 || track.playedCount > 0); //
if (shouldExportTrack)
{
// XML
curNode = [[NSXMLElement alloc] initWithXMLString: @"<TRACK n=\"\" name=\"\" played=\"\" rating=\"\" />" error:NULL];
[[curNode attributeForName: @"n" ] setStringValue:[NSString stringWithFormat: @"%i" , curLibTrack]];
// getTrackMetaName, ,
// , , ( Beyoncé Anggun)
[[curNode attributeForName: @"name" ] setStringValue:[self getTrackMetaName:track]];
[[curNode attributeForName: @"played" ] setStringValue:[NSString stringWithFormat: @"%i" , track.playedCount]];
[[curNode attributeForName: @"rating" ] setStringValue:[NSString stringWithFormat: @"%i" , track.rating]];
[rootNode addChild:curNode];
[curNode release];
}
}
//
[[xmlNew XMLData] writeToFile:( @"/Users/max/Desktop/old-library.xml" ) atomically:NO];
[xmlNew release];
}
* This source code was highlighted with Source Code Highlighter .
Conclusion
Work on the restoration of the long-suffering library has not yet been completed. It is necessary to deal with the sorting of tracks by the MetaName hash and with effective matching. There was an impression that it would be faster to fix everything manually, than to figure it all out for hours =)
Everything works fine. But in a semi-automatic mode, because there was no desire to mess around anymore.
On the other hand, I learned a lot of new things, instead of engaging in such a routine.
If there is an opportunity to automate something, it is better to do it once, than then periodically spend time on manual work.