I'm considering using YAML as part of my next iPhone application, but I haven't been able to find an Objective-C library to use.
The Wikipedia page for YAML mentions one, but the link is dead.
Is there an Objective-C library that can parse YAML into native collection objects (NSArray, NSDictionary, etc...)?
The Cocoa extensions for Syck are probably what you're looking for -- it's where the library that Shaggy Frog mentioned seems to be living these days.
You can try YAML.framework it's LibYAML based, it's fast and easy to use. Follows the same pattern as standard NSPropertyListSerialization.
You can use it for iOS (iPhone/iPad) development.
The YAMLKit framework is a thin wrapper around LibYAML. It does exactly what you want. For example:
[[YKParser alloc] init];
[p readString:#"- foo\n- bar\n- baz"];
id result = [p parse];
/* result is now an NSArray containing an NSArray with elements:
#"foo", #"bar", #"baz" */
[p release];
I recently wrote modern ObjC-YAML bindings, based on the standard NSCoder/NSKeyedArchiver interface: http://github.com/th-in-gs/YACYAML. I'm using them in my own projects, and intend to maintain them for at least as long as I continue to do so.
More here: http://www.blog.montgomerie.net/yacyaml
IF you are doing alot of c++ in your iPhone projects, then please have a look at yaml-cpp:
http://code.google.com/p/yaml-cpp/
has native iPhone support (via it's cmake build system)
has no dependencies beyond a good compiler and cmake
is very c++ friendly (thus, the name) with solid documentation (see the wiki/HowToParseADocument page)
I found this right from YAML's front page. But it looks like it might be out of date (c. 2004?), and the CVS link doesn't work for me.
I would bet that it's just a thin wrapper around an underlying C library like this or this... C code being "native" code that the Objective-C compiler will grok.
I found this question looking for YAML + objective C options. I ended up using this solution: https://github.com/icanzilb/JSONModel. Very cool, up to date and easy to use. Parses yaml directly into objective C models that you create inheriting the JSONModel class.
Related
My goal is to use libphonenumber, google's phone number handling library for an iPhone project I'm working on.
After downloading it (and many many hours), I complied the C++ version of the library, and it built a number ".a" files and ".dylib" files, of which I assumed I must import into my xCodeProject in order to access those C++ functions.
So I imported "libphonenumber.a" into my project, updated my target, build settings, build phases, and Library Search Paths as needed.
Building the xCode project for Device & Simulator pass, however give me the following warning:
"ld: warning: ignoring file ../XcodeProjects/libphonenumber/build/libphonenumber.dylib, file was built for unsupported file format which is not the architecture being linked (armv7)". (or i386 when compiling for simulator)
I understand from this that I must compile the libphonenumber for the correct i386 and/or armv7 architecture. So I tried to do that, but quickly realized this requires me to also rebuild libphonenumber's 3 dependent libraries as well, for the i386/armv7 architectures in order for libphonenumber's to now properly compile. Eventually, I gave up on that, it started to look like a big mess ahead of me.
After all my trials, I'm left with
3 Questions:
1) How to I compile libphonenumber C++ library for use with i386/armv6/armv7 architectures.
2) When using a c++ library, is my assumption correct? Is it a matter of simply importing the ".a" file that results from the compilation, and just point to it in the header of my xCode project files? What exactly are the steps for including and using c++ libraries and accessing their functions from objective-c inside xCode?
3) I did find LPNKit, an objective-c port for libphonenumber, however it is incomplete. Has anyone heard of it, and had any luck using it? Or does anyone have an objective-c port for libphonenumber that is complete, working, with instructions on how to compile and install it correctly?
Any help or advice on how to get this library working on iOS would be greatly appreciated.
Update:
I ended up using the javascript version of libphonenumber, adding all the files to my bundle, including all referenced javascript libraries and using UIWebview and stringByEvaluatingJavaScriptFromString to run functions. You could also have the UIWebview reference the javascript library online (I just preferred to have everything local as not to depend on an internet connection).
Here is a sample of what I did:
webView_ = [[UIWebView alloc] init];
[webView_ loadHTMLString:
#"<script src='base.js'></script>"
"<script>"
"goog.require('goog.dom');"
"goog.require('goog.json');"
"goog.require('goog.proto2.ObjectSerializer');"
"goog.require('goog.string.StringBuffer');"
"</script>"
"<script src=\"phonemetadata.pb.js\"></script>"
"<script src=\"phonenumber.pb.js\"></script>"
"<script src=\"metadata.js\"></script>"
"<script src=\"phonenumberutil.js\"></script>"
"<script src=\"asyoutypeformatter.js\"></script>"
"<script src=\"normalize.js\"></script>"
baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] resourcePath]]];
NSString *function = [[NSString alloc] initWithFormat: #"phoneNumberParser('%#','%#','')", phoneNumber, ISOCountryCode];
NSLog(#"function is: %#", function);
NSString *result =[webView_ stringByEvaluatingJavaScriptFromString:function];
The result variable gets me the formatted number.
I hope that helps anyone who ran into the same issue I did.
It has been ported by our team.
You can find it https://github.com/me2day/libPhoneNumber-iOS
Just note that libphonenumber Javascript library includes Google's closure library.
So you should consider, wrapping your Javascript call in a Javascript object and then compile it using closure builder in order to get an efficient and light weight script. (closure library before compilation : 18Mb, after compilation 300Kb !)
See above a sample of such a wrapper
goog.provide('sphone.phonenumber');
goog.require('goog.dom');
goog.require('goog.json');
goog.require('goog.proto2.ObjectSerializer');
goog.require('goog.array');
goog.require('goog.proto2.PbLiteSerializer');
goog.require('goog.string');
goog.require('goog.proto2.Message');
goog.require('goog.string.StringBuffer');
goog.require('i18n.phonenumbers.NumberFormat');
goog.require('i18n.phonenumbers.PhoneNumber');
goog.require('i18n.phonenumbers.PhoneNumberUtil');
sphone.phonenumber = function(phoneNumber, regionCode) {
this.getCountryCallCode=phonenumberGetCountryCallCode;
};
function phonenumberGetCountryCallCode(phoneNumber, regionCode) {
var phoneUtil = i18n.phonenumbers.PhoneNumberUtil.getInstance();
var number = phoneUtil.parseAndKeepRawInput(phoneNumber, regionCode);
return number.getCountryCode();
};
// Ensures the symbol will be visible after compiler renaming.
goog.exportSymbol('sphone.phonenumber', sphone.phonenumber);
1) Fix all the errors and re-compile all the dependencies for arm. As you said before.
2) Yes. According to kstenerud’s iOS-Universal-Framework
Using an iOS Framework
iOS frameworks are basically the same as regular dynamic Mac OS X frameworks, except they are statically linked.
To add a framework to your project, simply drag it into your project. When including headers from your framework, remember to use angle bracket syntax rather than quotes.
For example, with framework "MyFramework":
#import <MyFramework/MyClass.h>
This question Importing an external library in xcode - C++ follows like this: Import C++ library, use it, get errors from its dependency on built-in frameworks, import those built-in frameworks, everything works.
3) I would invest in LPNKit instead of fighting your way through option 1. You can both contribute and benefit from LPNKit. GitHub is a wonderful place and the great boost of this over option 1 is that you have another person (or people!) who have the same goal and will all work together to achieve it.
I read some info regarding getting .h files for undocumented API. Most of sources recommend class-dump (or class-dump-x and class-dump-z).
However it doesn't work with iPhone Security.framework. It doesn't contain Objective-C runtime information.
The only other way which I found is to use nm or otool. This will give the names of functions and disassembly for them.
Does anybody know some faster way to get undocumented functions signature than reading disassembly and trying to figure out what parameters go where and what could it be?
You mean this undocumented api, documented here..
Security.framework is not private or undocumented.
As far as headers go, installed on my harddrive in the 3.2 sdk i find:
/Security.framework/Headers/Security.h
/Security.framework/Headers/Secbase.h
/Security.framework/Headers/SecCertificate.h
/Security.framework/Headers/SecIdentitiy.h
/Security.framework/Headers/SecImportExport.h
/Security.framework/Headers/SecItem.h
/Security.framework/Headers/SecKey.h
/Security.framework/Headers/SecPolicy.h
/Security.framework/Headers/SecRandom.h
/Security.framework/Headers/SecTrust.h
As for a little reverse engineering 101, you should realise that a framework doesn't contain or in anyway have a use for header files, or function signatures. When provided they are solely for the benefit of the developer. There is no C or C++ or objective-c code in the compiled framework, only the raw machine code.
As you have seen, if objective-c was used Class-Dump can do a pretty good job of arranging objective-c symbols into something that looks like a header file, only missing type information that isn't used at runtime, so still not that useful.
If the source language was C then you are screwed. There may be a function name symbol but there is no info about arguments or return type.
There are bunch of additional undocumented API's which are not mentioned in official documentation. As example, part of them could be seen here:
http://www.opensource.apple.com/source/Security/Security-55163.44/sec/Security/
I'm attempting to follow this tutorial 'Demystifying Mail.app Plugins on Leopard' to build a Mail.app plugin. Instead of using PyObjC I'm trying to use MacRuby. I've got MacRuby 0.6 loaded up and I've gotten to this step in the tutorial (PyObjC code):
MVMailBundle = objc.lookUpClass('MVMailBundle')
I've search the web a bit but can't seem to find any information about loading the private framework 'MVMailBundle' in MacRuby. Any ideas?
Thanks in advance - AYAL
I think the idea is that this plugin will be loaded into Mail.app, which will already have loaded the private framework in question. So we just want to look up a class at runtime (which is what that Python snippet is doing — not loading a framework). The way to do this in MacRuby is MVMailBundle = NSClassFromString 'MVMailBundle'.
(You will need to include framework 'Cocoa' in order to get the NSClassFromString method, but I assume you'll have already done this.)
MacRuby uses garbage collection and Mail doesn't. You can't load a GC bundle into a non-GC app. So this is a dead-end.
I have mp3 files stored on the iPhone and I my application should to be able to read the ID3 information, i.e length in seconds, artist, etc.
Does anyone know how to do this or what library to use in Objective-C?
Your thoughts are much appreciated.
ID3 information can be read retrieving the kAudioFilePropertyInfoDictionary property of an audio file using the AudioFileGetProperty function of the AudioToolbox framework.
A detailed explanation is available at iphonedevbook.com
edit: Original link is now down. InformIT has some similar sample code, but it's not as complete.
Look into the Media Player framework:
Guide
Reference
All documentation
This requires that the MP3 in question is part of the iPod library on the phone.
For example, determining the name of every media file on the phone (including movies, podcasts, etc.):
MPMediaQuery *everything = [[MPMediaQuery alloc] init];
NSArray *itemsFromGenericQuery = [everything items];
for (MPMediaItem *item in itemsFromGenericQuery) {
NSString *itemTitle = [item valueForProperty:MPMediaItemPropertyTitle];
// ...
}
It appears that the following properties are available:
MPMediaItemPropertyMediaType
MPMediaItemPropertyTitle
MPMediaItemPropertyAlbumTitle
MPMediaItemPropertyArtist
MPMediaItemPropertyAlbumArtist
MPMediaItemPropertyGenre
MPMediaItemPropertyComposer
MPMediaItemPropertyPlaybackDuration
MPMediaItemPropertyAlbumTrackNumber
MPMediaItemPropertyAlbumTrackCount
MPMediaItemPropertyDiscNumber
MPMediaItemPropertyDiscCount
MPMediaItemPropertyArtwork
MPMediaItemPropertyLyrics
MPMediaItemPropertyIsCompilation
Doing this without going through the media player framework will be somewhat difficult, and will need an external framework.
There are not many ID3 parsing libraries out there that are not GPLed. There is on Objective-C framework that could probably be modified to work on the iPhone when statically linked, but it is LGPL. In order to satisfy the terms of the LGPL with a statically linked binary you have to provide enough of the intermediary components that someone could relink it with their own version of the library, which is difficult (but not impossible) for an iPhone app. Of course since I have not been in a position where I have had to do that I have not actually discussed it with a lawyer, and since I am not one you should not take that as authoritative.
Your best bet if you don't feel like consulting a lawyer is to use a more liberally licensed C library like libID3 and wrap that in some Objective C classes. I would also recommend just directly including the code rather than dealing with all the static library build and link issues, but that is just a personal style thing.
I need to write some code that will let me query a m4a file and extract the chapter information out. Including:
chapter name
chapter start time
chapter artwork
I did some quick searching and it seems this is viewed as proprietary information by Apple? I found some discussions, but most were from 2005. Also there have been some similar questions on here, but more for CREATING m4a files with chapters, not querying.
Is this just something I have to DIY, cause there isn't a nice apple API for me to use? Or am I missing something obvious?
Also, ideally I need whatever technique I end up using to work on the iPhone.
The metadata tags system is Apple-proprietary. To work with the tags, you have to (sigh) reverse-engineer it or work with a library that has already done this.
I found the following links, but honestly it seems like you will have to pull out the hex editor.
Binary format info (basic spec for generic tags)
Perl library for working with M4A files.
Turns out this is much simpler than talked about here in the "answers". Not sure if this works on the iPhone, but I just tested it in a command line app:
QTMovie* movie = [QTMovie movieWithFile:#"filename.m4a" error:nil];
NSInteger numChapters = [movie chapterCount];
NSLog(#"Number of Chapters: %d", numChapters);
NSArray* chapterArray = [movie chapters];
for ( NSDictionary* chapDict in chapterArray )
{
NSLog(#"%#", [chapDict objectForKey:#"QTMovieChapterName"] );
}
Easy as pie. DOH!
this library should solve your needs, but is not runnable on iphone without jailbreaking I would think. http://wmptagext.sourceforge.net/
oops if you need it to work on iphone there is probably an apple api to get this info. /me looks
it sounds like you need to play around with the ipodlibrary library....
http://developer.apple.com/iphone/library/documentation/Audio/Conceptual/iPodLibraryAccess_Guide/UsingTheiPodLibrary/UsingTheiPodLibrary.html#//apple_ref/doc/uid/TP40008765-CH101-SW1
If the files in question live in the iPod library,
maybe you can get your information via the MPMediaLibrary
query interface (3.0 upward).