YAML for ObjC
Introduction
YAML4ObjC is a wrapper class for LibYAML [1] to query YAML data more easily on iOS platforms, iPhone and iPad.
I used LibYAML directly to read configuration files of YAML objects in my project for iOS, but it is hard to use in my projects because I had to write the handler function for each projects like SAX parsers for XML documents 🙁
Thus, I aimed to handle YAML objects more easily only using Objective-C in the project and decided some implementation policies to handle YAML objects more easily for iOS developers as the following.
Resources
Using Only Standard iOS Objects
First, I would use only standard data objects of iOS such as NSArray and NSDictionary to hold YAML objects. After parsing YAML data using YAML4ObjC, the YAML nodes are translated into the following standard data structures in Objective-C on iOS.
YAML Node | iOS Object |
---|---|
Sequence | NSArray |
Scalar | NSString |
YPath
Next, I would support simple methods to get the node values like XPath. I was looking for the public specification for YAML or JSON version of XPATH [2][3][4], but I could not find it yet 🙁 Thus, I thought the following simple ABNF specification like XPath to get the node objects or values in YAML document easily.
YPath = [DocumentNo] '/' NodePath
NodePath = Node / NodePath '/' Node
Node = SequenceNo / MappingKeyName
DocumentNo = '[' [0-9]+ ']'
SequenceNo = '[' [0-9]+ ']'
MappingKeyName = [a-zA-Z0-9 ]+
Setup
Getting SDK Package
1. Get the SDK package from the following site.
Building and using example applications
1. Extract YAML4ObjC as the following steps:
$ unzip YAML4ObjC.zip
2. Add LibYAML package into the your SDK directory as the following
steps:
$ cd YamlObjCSDK
$ curl http://pyyaml.org/download/libyaml/yaml-0.1.3.tar.gz > yaml-0.1.3.tar.gz
$ tar xvfz yaml-0.1.3.tar.gz
$ mv yaml-0.1.3 libyaml
$ cd libyaml
$ ./configure
3. Open the project file in examples/ios/xcode/YamlViewer.xcodeproj
4. Build and Run app
Adding YamlObjCSDK to your project
1. Create your iOS project
2. Add source files of YamlObjCSDK, CGYAML.h and CGYAML.m, to select
YamlObjCSDK/YamlObjCSDK directory.
3. Add the following source files of libyaml.
libyaml/config.h
libyaml/src/api.c
libyaml/src/api.cdumper.c
libyaml/src/api.cemitter.c
libyaml/src/api.cloader.c
libyaml/src/api.cparser.c
libyaml/src/api.creader.c
libyaml/src/api.cscanner.c
libyaml/src/api.cwriter.c
3. Add “libyaml” and “libyaml/include” into “Heade Search Paths” of your build setting.
4. Add “-DHAVE_CONFIG into “Other C Flags” of your build setting.
5. Build and Run app
If you want to install LibYAML using the configure script, please use a
utility script file, yaml-configure-iosdev, as the following.
$ curl http://pyyaml.org/download/libyaml/yaml-0.1.3.tar.gz > yaml-0.1.3.tar.gz
$ tar xvfz yaml-0.1.3.tar.gz
$ cp yaml-configure-iosdev yaml-0.1.3
$ cd yaml-0.1.3
$ ./yaml-configure-iosdev
$ make
$ make install
Classes
YAML4ObjC is composed of only a CGYAML class as the following. I provide some useful category methods for NSObject to check the node type of YAML too. Please check the doxygen document to know the classes in more detail.
@interface CGYAML : NSObject {
}
- (id)init;
- (id)initWithString:(NSString *)yamlString;
- (id)initWithPath:(NSString *)yamlPath;
- (id)initWithData:(NSData *)yamlData;
- (id)initWithURL:(NSURL *)yamlURL;
- (BOOL)parseWithString:(NSString *)yamlString error:(NSError **)error;
- (BOOL)parseWithPath:(NSString *)yamlPath error:(NSError **)error;
- (BOOL)parseWithData:(NSData *)yamlData error:(NSError **)error;
- (BOOL)parseWithURL:(NSURL *)yamlURL error:(NSError **)error;
- (NSError *)error;
- (NSUInteger)numDocuments;
- (NSArray *)documents;
- (id)documentRootNodeAtIndex:(NSUInteger)index;
- (id)objectForYPath:(NSString *)yPath;
- (NSString *)valueForYPath:(NSString *)yPath;
- (BOOL)writeToFile:(NSString *)yPath;
@end
@interface NSObject(CGYAML)
- (BOOL) isYAMLSequenceNode;
- (BOOL) isYAMLScalarNode;
- (BOOL) isYAMLMappingNode;
@end
CGYAML offers two methods to get all values in the specified YAML data. In the first method, you can get the node values by traversing data
objects form the root object using YAML::documents or YAML::documentRootNodeAtIndex: as the following. To traverse the all values, please check the implementation of YAML::description in the source code.
CGYAML *yaml = [[CGYAML alloc] initWithString:.....];
for (id rootNode in [self documents]) {
if ([rootNode isYAMLSequenceNode) {
for (NSString *seqValue in rootNode) {
......
}
}
else if ([rootNode isYAMLMappingNode) {
for (NSString *mapKey in [rootNode allKeys]) {
NSString *mapValue = [rootNode objectForKey: mapKey];
......
}
}
}
In the next method, you can use YPath to get the node values using YAML::objectForYPath: or YAML::valueForYPath: as the following.
CGYAML *yaml = [[CGYAML alloc] initWithString:.....];
NSArray *seqNode = [yaml objectForKey:@"/[0]/american"];
for (NSString *seqValue in seqNode) {
......
}
NSString *value = [yaml valueForYPath:@"/[0]/american/[0]"];
.....
Programming Examples
Using some examples in YAML 1.1 specification, the following examples show how to get node values in YAML data using CGYAML methods.
Example 2.1 : Sequence of Scalars
YAML
- Sammy Sosa
- Ken Griffey
Using Standard Methods
CGYAML *yaml = [[CGYAML alloc] initWithString:.....];
NSArray *seqNode = [yaml documentRootNodeAtIndex:0];
NSString *value0 = [seqNode objectAtIndex:0];
NSString *value1 = [seqNode objectAtIndex:1];
NSString *value2 = [seqNode objectAtIndex:2];
Using YPath Methods
CGYAML *yaml = [[CGYAML alloc] initWithString:.....];
NSString *value0 = [yaml valueForYPath:@"/[0]"];
NSString *value1 = [yaml valueForYPath:@"/[1]"];
NSString *value2 = [yaml valueForYPath:@"/[2]"];
Example 2.2 : Mapping Scalars to Scalars
YAML
hr: 65 # Home runs
avg: 0.278 # Batting average
rbi: 147 # Runs Batted In
Using Standard Methods
CGYAML *yaml = [[CGYAML alloc] initWithString:.....];
NSDictionary *mapNode = [yaml documentRootNodeAtIndex:0];
NSString *value0 = [mapNode objectForKey:@"hr"];
NSString *value1 = [mapNode objectForKey:@"avg"];
NSString *value2 = [mapNode objectForKey:@"rbi"];
Using YPath Methods
CGYAML *yaml = [[CGYAML alloc] initWithString:.....];
NSString *value0 = [yaml valueForYPath:@"/hr"];
NSString *value1 = [yaml valueForYPath:@"/avg"];
NSString *value2 = [yaml valueForYPath:@"/rbi"];
Example 2.3 : Mapping Scalars to Sequences
YAML
american:
- Boston Red Sox
- Detroit Tigers
- New York Yankees
national:
- New York Mets
- Chicago Cubs
- Atlanta Braves
Using Standard Methods
CGYAML *yaml = [[CGYAML alloc] initWithString:.....];
NSDictionary *mapNode = [yaml documentRootNodeAtIndex:0];
NSArray *seqNode = [mapNode objectForKey:@"american"];
NSString *american0 = [seqNode objectAtIndex:0];
NSString *american1 = [seqNode objectAtIndex:1];
NSString *american2 = [seqNode objectAtIndex:2];
NSArray *seqNode = [mapNode objectForKey:@"national"];
NSString *national0 = [seqNode objectAtIndex:0];
NSString *national1 = [seqNode objectAtIndex:1];
NSString *national2 = [seqNode objectAtIndex:2];
Using YPath Methods
CGYAML *yaml = [[CGYAML alloc] initWithString:.....];
NSString *american0 = [yaml valueForYPath:@"/american/[0]"];
NSString *american1 = [yaml valueForYPath:@"/american/[1]"];
NSString *american2 = [yaml valueForYPath:@"/american/[2]"];
NSString *national0 = [yaml valueForYPath:@"/national/[0]"];
NSString *national1 = [yaml valueForYPath:@"/national/[1]"];
NSString *national2 = [yaml valueForYPath:@"/national/[2]"];
Example 2.4 : Sequence of Mappings
YAML
-
name: Mark McGwire
hr: 65
avg: 0.278
-
name: Sammy Sosa
hr: 63
avg: 0.288
Using Standard Methods
CGYAML *yaml = [[CGYAML alloc] initWithString:.....];
NSArray *seqNode = [yaml documentRootNodeAtIndex:0];
NSDictionary *mapNode = [seqNode objectAtIndex:0];
NSString *value0n = [mapNode objectForKey:@"name"];
NSString *value0h = [mapNode objectForKey:@"hr"];
NSString *value0a = [mapNode objectForKey:@"avg"];
NSDictionary *mapNode = [seqNode objectAtIndex:1];
NSString *value1n = [mapNode objectForKey:@"name"];
NSString *value1h = [mapNode objectForKey:@"hr"];
NSString *value1a = [mapNode objectForKey:@"avg"];
Using YPath Methods
CGYAML *yaml = [[CGYAML alloc] initWithString:.....];
NSString *value0n = [yaml valueForYPath:@"/[0]/name"];
NSString *value0h = [yaml valueForYPath:@"/[0]/hr"];
NSString *value0a = [yaml valueForYPath:@"/[0]/avg"];
NSString *value1n = [yaml valueForYPath:@"/[1]/name"];
NSString *value1h = [yaml valueForYPath:@"/[1]/hr"];
NSString *value1a = [yaml valueForYPath:@"/[1]/avg"];
Example 2.7 : Single Document with Two Comments
YAML
# Ranking of 1998 home runs
---
- Mark McGwire
- Sammy Sosa
- Ken Griffey
# Team ranking
---
- Chicago Cubs
- St Louis Cardinals
Using Standard Methods
CGYAML *yaml = [[CGYAML alloc] initWithString:.....];
NSArray *seqNode = [yaml documentRootNodeAtIndex:0];
NSString *value00 = [seqNode objectAtIndex:0];
NSString *value01 = [seqNode objectAtIndex:1];
NSString *value02 = [seqNode objectAtIndex:2];
NSArray *seqNode = [yaml documentRootNodeAtIndex:1];
NSString *value10 = [seqNode objectAtIndex:0];
NSString *value10 = [seqNode objectAtIndex:1];
Using YPath Methods
CGYAML *yaml = [[CGYAML alloc] initWithString:.....]
NSString *value00 = [yaml valueForYPath:@"[0]/[0]"];
NSString *value01 = [yaml valueForYPath:@"[0]/[1]"];
NSString *value02 = [yaml valueForYPath:@"[0]/[2]"];
NSString *value10 = [yaml valueForYPath:@"[1]/[0]"];
NSString *value11 = [yaml valueForYPath:@"[1]/[1]"];
References
- [1] LibYAML
- [2] XML Matters: YAML improves on
XML - [3] JSONPath – XPath for JSON
- [4] YAML4R
Pingback: Leandro Farland
Pingback: Lila Lovely
Pingback: cheap-premium-domains
Pingback: Quality Assignment Help
Pingback: Get Assignment Help
Pingback: valentine gift
Pingback: valentine gift for her
Pingback: organic foot lotion
Pingback: natural sunscreen
Pingback: valentine gift for her
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: spaceros
Pingback: robotics case study
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Reputation Defenders
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: grand rapids dentist
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: https://gquery.org/
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: 인터넷카지노사이트
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: Click Here
Pingback: 실제 현금 카지노
Pingback: 무료 카지노 게임
Pingback: premium-domain-name
Pingback: premium-domains
Pingback: superhero
Pingback: limited company setup
Pingback: Google reviews
Pingback: Porn Star in Australia
Pingback: reputation defenders
Pingback: 2023 Books
Pingback: funeral directory
Pingback: tombstones
Pingback: burial place
Pingback: IRA Empire
Pingback: football betting tips for today
Pingback: Chirurgie Tunisie
Pingback: Chirurgiens esthétique Tunisie
Pingback: National Chi Nan University
Pingback: Alumni network
Pingback: Top-quality learning environment
Pingback: دراسة ادارة الاعمال بجامعة المستقبل
Pingback: Accounting courses
Pingback: Higher education in political mass media
Pingback: Faculty of economics Contact
Pingback: خطوات التقديم بالكلية
Pingback: Rota evaporators
Pingback: Healthcare standards
Pingback: Academic Advisor
Pingback: Continuing Education
Pingback: Future University
Pingback: Research opportunities
Pingback: Online Learning
Pingback: social reform
Pingback: PHD dental in future university in egypt
Pingback: افضل جامعة لدراسة ادارة الاعمال
Pingback: International student admissions to future university
Pingback: HR management
Pingback: MBA courses in Egypt
Pingback: Business administration program Egypt
Pingback: متطلبات كشف الدرجات لجامعة المستقبل
Pingback: Field Visits
Pingback: استمارة طلب التقديم بجامعة المستقبل
Pingback: fue
Pingback: MBA curriculum in Egypt
Pingback: Dental specialization programs
Pingback: education system
Pingback: ?????? ???????
Pingback: Promoting Innovation and Creativity
Pingback: Aims and Goals symposium
Pingback: Medicinal Chemistry
Pingback: https://www.kooky.domains/post/what-are-web3-domains
Pingback: https://www.kooky.domains/post/exploring-the-potential-of-web3-domains-for-decentralized-applications
Pingback: Faculty of Economics and Political Science
Pingback: Withdrawal and Add/Drop Dates
Pingback: MSc in pharmacy
Pingback: كلمة عميد كلية الصيدلة بجامعة المستقبل
Pingback: تقدم تكنولوجي
Pingback: Structural Engineering and Construction Management
Pingback: the role played by the students of the College of Engineering to advance the country
Pingback: برامج علوم الكمبيوتر في مصر
Pingback: higher education institutions
Pingback: first term exams
Pingback: digital press
Pingback: علم العقاقير والسموم
Pingback: التعليم المستمر لطب الأسنان
Pingback: ما هي افضل الكليات الخاصه
Pingback: ما هي الجامعات الخاصة المعتمدة في مصر
Pingback: امتحانات القبول لجامعة المستقبل
Pingback: Maillot de football
Pingback: Maillot de football
Pingback: Maillot de football
Pingback: Maillot de football
Pingback: Maillot de football
Pingback: Maillot de football
Pingback: Maillot de football
Pingback: Maillot de football
Pingback: Maillot de football
Pingback: Maillot de football
Pingback: SEOSolutionVIP Fiverr
Pingback: SEOSolutionVIP Fiverr
Pingback: SEOSolutionVIP Fiverr