Contents
- 1 YAML for ObjC
- 1.1 Introduction
- 1.2 Resources
- 1.3 Setup
- 1.4 Classes
- 1.5 Programming Examples
- 1.5.1 Example 2.1 : Sequence of Scalars
- 1.5.2 Using YPath Methods
- 1.5.3 Example 2.2 : Mapping Scalars to Scalars
- 1.5.4 Using YPath Methods
- 1.5.5 Example 2.3 : Mapping Scalars to Sequences
- 1.5.6 Using YPath Methods
- 1.5.7 Example 2.4 : Sequence of Mappings
- 1.5.8 Using YPath Methods
- 1.5.9 Example 2.7 : Single Document with Two Comments
- 1.5.10 Using YPath Methods
- 1.6 References
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