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

162 thoughts on “YAML for ObjC

  1. Pingback: Leandro Farland

  2. Pingback: Lila Lovely

  3. Pingback: cheap-premium-domains

  4. Pingback: Quality Assignment Help

  5. Pingback: Get Assignment Help

  6. Pingback: valentine gift

  7. Pingback: valentine gift for her

  8. Pingback: organic foot lotion

  9. Pingback: natural sunscreen

  10. Pingback: valentine gift for her

  11. Pingback: Click Here

  12. Pingback: Click Here

  13. Pingback: Click Here

  14. Pingback: Click Here

  15. Pingback: Click Here

  16. Pingback: Click Here

  17. Pingback: Click Here

  18. Pingback: Click Here

  19. Pingback: Click Here

  20. Pingback: Click Here

  21. Pingback: Click Here

  22. Pingback: Click Here

  23. Pingback: Click Here

  24. Pingback: Click Here

  25. Pingback: Click Here

  26. Pingback: Click Here

  27. Pingback: Click Here

  28. Pingback: Click Here

  29. Pingback: Click Here

  30. Pingback: spaceros

  31. Pingback: robotics case study

  32. Pingback: Click Here

  33. Pingback: Click Here

  34. Pingback: Click Here

  35. Pingback: Reputation Defenders

  36. Pingback: Click Here

  37. Pingback: Click Here

  38. Pingback: Click Here

  39. Pingback: Click Here

  40. Pingback: Click Here

  41. Pingback: Click Here

  42. Pingback: Click Here

  43. Pingback: Click Here

  44. Pingback: Click Here

  45. Pingback: Click Here

  46. Pingback: Click Here

  47. Pingback: Click Here

  48. Pingback: Click Here

  49. Pingback: Click Here

  50. Pingback: Click Here

  51. Pingback: Click Here

  52. Pingback: Click Here

  53. Pingback: Click Here

  54. Pingback: Click Here

  55. Pingback: Click Here

  56. Pingback: grand rapids dentist

  57. Pingback: Click Here

  58. Pingback: Click Here

  59. Pingback: Click Here

  60. Pingback: https://gquery.org/

  61. Pingback: Click Here

  62. Pingback: Click Here

  63. Pingback: Click Here

  64. Pingback: Click Here

  65. Pingback: Click Here

  66. Pingback: 인터넷카지노사이트

  67. Pingback: Click Here

  68. Pingback: Click Here

  69. Pingback: Click Here

  70. Pingback: Click Here

  71. Pingback: Click Here

  72. Pingback: Click Here

  73. Pingback: Click Here

  74. Pingback: Click Here

  75. Pingback: Click Here

  76. Pingback: Click Here

  77. Pingback: Click Here

  78. Pingback: Click Here

  79. Pingback: Click Here

  80. Pingback: Click Here

  81. Pingback: Click Here

  82. Pingback: 실제 현금 카지노

  83. Pingback: 무료 카지노 게임

  84. Pingback: premium-domain-name

  85. Pingback: premium-domains

  86. Pingback: superhero

  87. Pingback: limited company setup

  88. Pingback: Google reviews

  89. Pingback: Porn Star in Australia

  90. Pingback: reputation defenders

  91. Pingback: 2023 Books

  92. Pingback: funeral directory

  93. Pingback: tombstones

  94. Pingback: burial place

  95. Pingback: IRA Empire

  96. Pingback: football betting tips for today

  97. Pingback: Chirurgie Tunisie

  98. Pingback: Chirurgiens esthétique Tunisie

  99. Pingback: National Chi Nan University

  100. Pingback: Alumni network

  101. Pingback: Top-quality learning environment

  102. Pingback: دراسة ادارة الاعمال بجامعة المستقبل

  103. Pingback: Accounting courses

  104. Pingback: Higher education in political mass media

  105. Pingback: Faculty of economics Contact

  106. Pingback: خطوات التقديم بالكلية

  107. Pingback: Rota evaporators

  108. Pingback: Healthcare standards

  109. Pingback: Academic Advisor

  110. Pingback: Continuing Education

  111. Pingback: Future University

  112. Pingback: Research opportunities

  113. Pingback: Online Learning

  114. Pingback: social reform

  115. Pingback: PHD dental in future university in egypt

  116. Pingback: افضل جامعة لدراسة ادارة الاعمال

  117. Pingback: International student admissions to future university

  118. Pingback: HR management

  119. Pingback: MBA courses in Egypt

  120. Pingback: Business administration program Egypt

  121. Pingback: متطلبات كشف الدرجات لجامعة المستقبل

  122. Pingback: Field Visits

  123. Pingback: استمارة طلب التقديم بجامعة المستقبل

  124. Pingback: fue

  125. Pingback: MBA curriculum in Egypt

  126. Pingback: Dental specialization programs

  127. Pingback: education system

  128. Pingback: ?????? ???????

  129. Pingback: Promoting Innovation and Creativity

  130. Pingback: Aims and Goals symposium

  131. Pingback: Medicinal Chemistry

  132. Pingback: https://www.kooky.domains/post/what-are-web3-domains

  133. Pingback: https://www.kooky.domains/post/exploring-the-potential-of-web3-domains-for-decentralized-applications

  134. Pingback: Faculty of Economics and Political Science

  135. Pingback: Withdrawal and Add/Drop Dates

  136. Pingback: MSc in pharmacy

  137. Pingback: كلمة عميد كلية الصيدلة بجامعة المستقبل

  138. Pingback: تقدم تكنولوجي

  139. Pingback: Structural Engineering and Construction Management

  140. Pingback: the role played by the students of the College of Engineering to advance the country

  141. Pingback: برامج علوم الكمبيوتر في مصر

  142. Pingback: higher education institutions

  143. Pingback: first term exams

  144. Pingback: digital press

  145. Pingback: علم العقاقير والسموم

  146. Pingback: التعليم المستمر لطب الأسنان

  147. Pingback: ما هي افضل الكليات الخاصه

  148. Pingback: ما هي الجامعات الخاصة المعتمدة في مصر

  149. Pingback: امتحانات القبول لجامعة المستقبل

  150. Pingback: Maillot de football

  151. Pingback: Maillot de football

  152. Pingback: Maillot de football

  153. Pingback: Maillot de football

  154. Pingback: Maillot de football

  155. Pingback: Maillot de football

  156. Pingback: Maillot de football

  157. Pingback: Maillot de football

  158. Pingback: Maillot de football

  159. Pingback: Maillot de football

  160. Pingback: SEOSolutionVIP Fiverr

  161. Pingback: SEOSolutionVIP Fiverr

  162. Pingback: SEOSolutionVIP Fiverr