YamlSwift - Load YAML and JSON documents using Swift

Related tags

JSON YamlSwift
Overview

YamlSwift

Load YAML and JSON documents using Swift.

YamlSwift parses a string of YAML document(s) (or a JSON document) and returns a Yaml enum value representing that string.

Install

Use Carthage to build and install.

Or use CocoaPods : Add pod 'Yaml' to your Podfile and run pod install.

It supports Swift Package Manager.

        .package(
            url: "https://github.com/behrang/YamlSwift.git",
            from: "

And:

        .target(
            name: "YourProject",
            dependencies: ["Yaml"]),

API

import

To use it, you should import it using the following statement:

import Yaml

Yaml

A Yaml value can be any of these cases:

enum Yaml {
  case null
  case bool(Bool)
  case int(Int)
  case double(Double)
  case string(String)
  case array([Yaml])
  case dictionary([Yaml: Yaml])
}

Yaml.load

Yaml.load (String) throws -> Yaml

Takes a string of a YAML document and returns a Yaml enum.

let value = try! Yaml.load("a: 1\nb: 2")
print(value["a"])  // Int(1)
print(value["b"])  // Int(2)
print(value["c"])  // Null

If the input document is invalid or contains more than one YAML document, an error is thrown.

do {
  let value = try Yaml.load("a\nb: 2")
}
catch {
  print(error)  // expected end, near "b: 2"
}

Yaml.loadMultiple

Yaml.loadMultiple (String) throws -> [Yaml]

Takes a string of one or more YAML documents and returns [Yaml].

let value = try! Yaml.loadMultiple("---\na: 1\nb: 2\n---\na: 3\nb: 4")
print(value[0]["a"])  // Int(1)
print(value[1]["a"])  // Int(3)

It will throw an error if an error is encountered in any of the documents.

Yaml#[Int] -> Yaml

value[Int] -> Yaml
value[Int] = Yaml

If used on a Yaml.array value, it will return the value at the specified index. If the index is invalid or the value is not a Yaml.array, Yaml.null is returned. You can also set a value at a specific index. Enough elements will be added to the wrapped array to set the specified index. If the value is not a Yaml.array, it will change to it after set.

var value = try! Yaml.load("- Behrang\n- Maryam")
print(value[0])  // String(Behrang)
print(value[1])  // String(Maryam)
print(value[2])  // Null
value[2] = "Radin"
print(value[2])  // String(Radin)

Yaml#[Yaml] -> Yaml

value[Yaml] -> Yaml
value[Yaml] = Yaml

If used on a Yaml.dictionary value, it will return the value for the specified key. If a value for the specified key does not exist, or value is not a Yaml.dictionary, Yaml.null is returned. You can also set a value for a specific key. If the value is not a Yaml.dictionary, it will change to it after set.

Since Yaml is a literal convertible type, you can pass simple values to this method.

var value = try! Yaml.load("first name: Behrang\nlast name: Noruzi Niya")
print(value["first name"])  // String(Behrang)
print(value["last name"])  // String(Noruzi Niya)
print(value["age"])  // Null
value["first name"] = "Radin"
value["age"] = 1
print(value["first name"])  // String(Radin)
print(value["last name"])  // String(Noruzi Niya)
print(value["age"])  // Int(1)

Yaml#bool

value.bool -> Bool?

Returns an Optional value. If the value is a Yaml.bool value, the wrapped value is returned. Otherwise nil is returned.

let value = try! Yaml.load("animate: true\nshow tip: false\nusage: 25")
print(value["animate"].bool)  // Optional(true)
print(value["show tip"].bool)  // Optional(false)
print(value["usage"].bool)  // nil

Yaml#int

value.int -> Int?

Returns an Optional value. If the value is a Yaml.int value, the wrapped value is returned. Otherwise nil is returned.

let value = try! Yaml.load("a: 1\nb: 2.0\nc: 2.5")
print(value["a"].int)  // Optional(1)
print(value["b"].int)  // Optional(2)
print(value["c"].int)  // nil

Yaml#double

value.double -> Double?

Returns an Optional value. If the value is a Yaml.double value, the wrapped value is returned. Otherwise nil is returned.

let value = try! Yaml.load("a: 1\nb: 2.0\nc: 2.5\nd: true")
print(value["a"].double)  // Optional(1.0)
print(value["b"].double)  // Optional(2.0)
print(value["c"].double)  // Optional(2.5)
print(value["d"].double)  // nil

Yaml#string

value.string -> String?

Returns an Optional value. If the value is a Yaml.string value, the wrapped value is returned. Otherwise nil is returned.

let value = try! Yaml.load("first name: Behrang\nlast name: Noruzi Niya\nage: 33")
print(value["first name"].string)  // Optional("Behrang")
print(value["last name"].string)  // Optional("Noruzi Niya")
print(value["age"].string)  // nil

Yaml#array

value.array -> [Yaml]?

Returns an Optional> value. If the value is a Yaml.array value, the wrapped value is returned. Otherwise nil is returned.

let value = try! Yaml.load("languages:\n - Swift: true\n - Objective C: false")
print(value.array)  // nil
print(value["languages"].array)  // Optional([Dictionary([String(Swift): Bool(true)]), Dictionary([String(Objective C): Bool(false)])])

Yaml#dictionary

value.dictionary -> [Yaml: Yaml]?

Returns an Optional> value. If the value is a Yaml.dictionary value, the wrapped value is returned. Otherwise nil is returned.

let value = try! Yaml.load("- Swift: true\n- Objective C: false")
print(value.dictionary)  // nil
print(value[0].dictionary)  // Optional([String(Swift): Bool(true)])

Yaml#count

value.count -> Int?

Returns an Optional value. If the value is either a Yaml.array or a Yaml.dictionary value, the count of elements is returned. Otherwise nil is returned.

let value = try! Yaml.load("- Swift: true\n- Objective C: false")
print(value.count)  // Optional(2)
print(value[0].count)  // Optional(1)
print(value[0]["Swift"].count)  // nil

License

MIT

Comments
  • increased compatibility

    increased compatibility

    replaced replace(regex: NSRegularExpression, template: String) with String.replace(String, with:String). It is simpler to read and compatible with linux. also added String.count for readability over count(String). related to #19 EDIT: new commit, referenced issue

    opened by revanistT3-zz 16
  • Error(

    Error("expected dedent, near \"user:\\n password: test\\n username: test\\n\"")

    I've got some valid yaml that I'm importing from my filesystem, I'd like to parse it but YamlSwift throws an error. I'm not 100% sure I'm doing everything right mind.

    apiVersion: v1
    clusters:
    - cluster:
        insecure-skip-tls-verify: true
        username: test
    - name: staging
      user:
        password: test
        username: test
    
    readString = try NSString(contentsOfFile: filePath, encoding: NSUTF8StringEncoding) as String
    
    if (readString != "") {
         let value = Yaml.load(readString)
         if (value.error != ""){
              print(value.error)
         }
         print(value)
    }
    
    

    results in

    Error("expected dedent, near \"user:\\n    password: test\\n    username: test\\n\"")
    
    opened by rawlingsj 14
  • switch Foundation dependant code to Standard Library

    switch Foundation dependant code to Standard Library

    swift 2 is getting more popular, especially as it has become open source. The type of people who go to github are likely using open source tools (swift 2) and operating systems. Linux (an open source os) only supports swift 2.

    opened by revanistT3-zz 14
  • Feature/prefix yaml

    Feature/prefix yaml

    • Rename Result to YAMLResult as Result is such a common case. Internal isn't enough. It can't be nested as its generic. Maybe in Future Swift updates.
    • Change project structure in preparation for Swift Package Manager.
    • Make it easier for people to extract relevant source code for inline dependencies
    opened by seivan 8
  • Encapsulation and Swift_3_guidelines

    Encapsulation and Swift_3_guidelines

    This also contains https://github.com/behrang/YamlSwift/pull/37 I made two separate PR in case this is too much of a change.

    • Moved - and == operator to be defined inside Yaml.
    • Switching all enums to be lowercase. Using _ prefix on keywords like '_true' and '_false'.
    • Encapsulated Context under Yaml
    • Created an internalstruct Regex, encapsulated under Yaml with three internal static functions. The rest of the code in Regex.swift are private
    • Made Result internal instead of public as you can't nest generic types.
    • Renamed files using YAML Prefix. This helps when using in-project source instead of frameworks.
    • Yaml static functions now throw a ResultError instead of returning a Result<T> monad.
    • Moving everything that is used in a single scope to private and single files to fileprivate
    • The rest are moved into static functions nested under Yaml ->
    • Added a .travis.yml file to run iOS Scheme for now, will add others some other time.
    • Updated Readme to reflect API changes.

    I made Result internal, and changed the public functions to throw an error (idiomatic Swift) instead of returning a monad. I know that's a significant change, but even if I do personally prefer monads and Result works like an optional (which is also a monad), I'd think it would suit more people with throwable functions.

    opened by seivan 8
  • Support Swift 2.3

    Support Swift 2.3

    • Run convert to current Swift syntax using Swift 2.3
      • No codes are changed.
      • LastSwiftMigration on each targets
      • SWIFT_VERSION = 2.3
    • Update project settings to recommended settings of Xcode 8 beta 1
    • Add SWIFT_VERSION xcconfig to podspec
    opened by norio-nomura 6
  • Project reorganization. Addition of additional targets and schemes for iOS

    Project reorganization. Addition of additional targets and schemes for iOS

    Changes in this pull request:

    • Renamed the existing Yaml target to Yaml OSX, but kept its product name as Yaml.framework. Renamed its scheme to Yaml OSX.
    • Added an iOS target (Yaml iOS), product (Yaml.framework) and scheme (Yaml iOS). Shared this scheme.
    • Reorganized the on-disk structure to better reflect standard Xcode project organization, e.g., src -> Yaml and test -> YamlTests. Deleted the src and test folders.
    • Deleted and ignored the project.xcworkspace file inside of the Yaml.xcodeproj. (No need to check this in.)
    • Added xcuserdata to .gitignore.
    • Deleted the Cartfile since it was empty and shouldn't be checked in anyway.
    • Verified that the all of the tests work in both schemes.
    opened by Revolucent 5
  • "Expected dedent" error when trying top parse YAML file.

    Greetings!

    Using your API to parse YAML files in our project, but getting a "expected dedent, near " error in some random files.

    For example, trying to parse the following text:

    título: "Freios ABS"
    inédita: False
    fonte: "Enem 2012, Caderno amarelo, Questão 52"
    
    área: "Ciências da Natureza e suas Tecnologias"
    disciplina: "Física"
    
    pergunta: |
      Os freios ABS são uma importante medida de segurança no trânsito, os quais funcionam para impedir o travamento das rodas do carro quando o sistema de freios é acionado, liberando as rodas quando estão no limiar do deslizamento. Quando as rodas travam, a força de frenagem é governada pelo atrito cinético.
    
      As representações esquemáticas da força de atrito *f*𝒂𝑡 entre os pneus e a pista, em função da pressão *p* aplicada no pedal de freio, para carros sem ABS e com ABS, respectivamente, são:
    
    respostas:
      a: "![A](./A.png)"
    
      b: "![B](./B.png)"
    
      c: "![C](./C.png)"
    
      d: "![D](./D.png)"
    
      e: "![E](./E.png)"
    
    correta: "a"
    
    dificuldade:
      média: 0.42
      desvio padrão: 0.15
    

    Returns the following error:

    expected dedent, near "respostas:\n \n a: \"![A](./A.png)\"\n \n b: \"![B](./"

    Is this a known issue, and do you have any workaround for it? Thank you very much!

    opened by atmonello 5
  • Fails to parse (awkward looking?) array

    Fails to parse (awkward looking?) array

    It appears YamlSwift fails to parse this:

    array: [item1,
    item2, item3]
    

    The indenting looks a little odd to me.., but it appears to pass the Yaml linters I tried:

    • http://yaml-online-parser.appspot.com/?yaml=array%3A+%5Bitem1%2C%0Aitem2%2C+item3%5D&type=json
    • http://www.yamllint.com (couldn't find a direct link with the Yaml pre-filled out)

    So far I've traced this to be an extra dedent token between the two lines, i.e.:

    ... string(item1), comma, dedent, newline, string(item2), ...
    

    Any ideas?


    Sample code

    import Yaml
    
    let yamlString = "array: [item1,\nitem2, item3]"
    Yaml.debug(yamlString)
    

    Output

    (line breaks added for readability)

    ====== Tokens:
    [(Yaml.Yaml.TokenType.string, "array"),
    (Yaml.Yaml.TokenType.colon, ":"), 
    (Yaml.Yaml.TokenType.indent, ""), 
    (Yaml.Yaml.TokenType.space, " "), 
    (Yaml.Yaml.TokenType.openSB, "["),
    (Yaml.Yaml.TokenType.string, "item1"), 
    (Yaml.Yaml.TokenType.comma, ","), 
    (Yaml.Yaml.TokenType.dedent, ""), 
    (Yaml.Yaml.TokenType.newLine, "\n"), 
    (Yaml.Yaml.TokenType.string, "item2"), 
    (Yaml.Yaml.TokenType.comma, ","),
    (Yaml.Yaml.TokenType.space, " "), 
    (Yaml.Yaml.TokenType.string, "item3"),
    (Yaml.Yaml.TokenType.closeSB, "]"),
    (Yaml.Yaml.TokenType.end, "")]
    ~~~~~~
    expected comma, near "\nitem2, item3]"
    
    opened by darrenclark 4
  • Support ordered keys

    Support ordered keys

    It would be great if we could keep the order of the keys as the same as the source file parsed from. I know JSON doesn't maintain order, but it could be useful in scenarios where YAML is used for configurations and we need access to defined variables within the YAML tree.

    opened by seivan 4
  • Add explicit self identifier for measureBlock call

    Add explicit self identifier for measureBlock call

    And add an EOF newline to the file, apparently.

    This change is to fix a carthage build failure after upgrading to XCode 7.1:

    .../Carthage/Checkouts/YamlSwift/YamlTests/ExampleTests.swift:454:17: error: reference to property 'exampleYaml' in closure requires explicit 'self.' to make capture semantics explicit

    opened by adamcin 4
  • Linux: error: product dependency 'Yaml' in package 'YamlSwift' not found

    Linux: error: product dependency 'Yaml' in package 'YamlSwift' not found

    I've added YamlSwift to my Project package deps:

       dependencies: [
           .package(url: "https://github.com/behrang/YamlSwift.git", from: "3.4.4"),
       ]
    

    and to target deps:

                .target(
                name: "MyAppTarget",
                dependencies: [
                   .product(name: "Yaml", package: "YamlSwift"),
                ],   
    

    Then Yaml works fine on native macOS.
    But when I try to compile app code in Docker swift container (from swift:5.3-focal image) it will fail:

    error: product dependency 'Yaml' in package 'YamlSwift' not found
    
    bug question 
    opened by vitalz 2
  • a problem

    a problem

    let frontMatter: Yaml = ["title": "Welcome to Spelt", "layout": "post", "date": .string(dateString)]
    let generatedContents = frontMatter.string ?? "" + "---\n\n" + postContents
    

    can we frontMatter.string get value in this case? dump

    question 
    opened by OHeroJ 2
  • Fail to parse simple yaml file

    Fail to parse simple yaml file

    File exmplae:

      - name: asd
        back:
        - img: qweqwe
          offset: qweqwe
    

    Error message:

    Yaml.Yaml.ResultError.message(Optional("expected dedent, near \"offset: qweqwe\\n\\n\""))
    

    Steps:

    1. Install YamlSwift with Pods (added pod 'Yaml' to Podfile)
    2. Changed swift language to swift 4 (it doesn't compiles in swift5)
    3. Try to load example above
    opened by bakwc 0
  • Does date/time parsing work?

    Does date/time parsing work?

    As I understand it, Yaml is supposed to understand dates & times. When I parse a file like this:

    datetime: 2001-12-15T02:59:43.1Z
    

    I get:

    Dictionary([String(datetime): String(2001-12-15T02:59:43.1Z)])
    

    But I was hoping for

    Dictionary([String(datetime): Date(2018-03-29 20:15:16 +0000)])
    
    opened by JetForMe 7
  • Use CI to build dynamic framework on pushed tags if tests succeed

    Use CI to build dynamic framework on pushed tags if tests succeed

    Would require:

    • [ ] https://github.com/behrang/YamlSwift/issues/55
    • [ ] https://github.com/behrang/YamlSwift/issues/54

    I could implement this as I've done it in the past. It would use Github releases to upload artefacts, in our case a YamlSwift_framework.zip attached to a tag. It would work with Carthage to get prebuilt binaries.

    enhancement question 
    opened by seivan 3
Owner
Behrang Norouzinia
Behrang Norouzinia
Swift parser for JSON Feed — a new format similar to RSS and Atom but in JSON.

JSONFeed Swift parser for JSON Feed — a new format similar to RSS and Atom but in JSON. For more information about this new feed format visit: https:/

Toto Tvalavadze 31 Nov 22, 2021
JSEN (JSON Swift Enum Notation) is a lightweight enum representation of a JSON, written in Swift.

JSEN /ˈdʒeɪsən/ JAY-sən JSEN (JSON Swift Enum Notation) is a lightweight enum representation of a JSON, written in Swift. A JSON, as defined in the EC

Roger Oba 8 Nov 22, 2022
Swift-json - High-performance json parsing in swift

json 0.1.4 swift-json is a pure-Swift JSON parsing library designed for high-per

kelvin 43 Dec 15, 2022
JSON-Practice - JSON Practice With Swift

JSON Practice Vista creada con: Programmatic + AutoLayout Breve explicación de l

Vanesa Giselle Korbenfeld 0 Oct 29, 2021
Ss-json - High-performance json parsing in swift

json 0.1.1 swift-json is a pure-Swift JSON parsing library designed for high-per

kelvin 43 Dec 15, 2022
JSONNeverDie - Auto reflection tool from JSON to Model, user friendly JSON encoder / decoder, aims to never die

JSONNeverDie is an auto reflection tool from JSON to Model, a user friendly JSON encoder / decoder, aims to never die. Also JSONNeverDie is a very important part of Pitaya.

John Lui 454 Oct 30, 2022
AlamofireObjectMappe - An Alamofire extension which converts JSON response data into swift objects using ObjectMapper

AlamofireObjectMapper An extension to Alamofire which automatically converts JSON response data into swift objects using ObjectMapper. Usage Given a U

Tristan Himmelman 2.6k Dec 29, 2022
Developed with use Swift language. As a third party library used SDWebImage. JSON parsing using URLSession with TMDB API. This app provide by the Core Data structure.

Capstone Project ?? About Developed with use Swift language. As a third party library used SDWebImage. JSON parsing using URLSession with TMDB API. Ad

Ensar Batuhan Unverdi 9 Aug 22, 2022
Easy JSON to NSObject mapping using Cocoa's key value coding (KVC)

#Motis Object Mapping Easy JSON to NSObject mapping using Cocoa's key value coding (KVC) Motis is a user-friendly interface with Key Value Coding that

Mobile Jazz 249 Jun 29, 2022
Coding Challenge using NYC JSON data

Coding Challenge using NYC JSON data This was my submission to JPMorgan's code challenge prior to an interview. It represents my solution to asyncrono

null 0 Dec 9, 2021
Nikolai Saganenko 1 Jan 9, 2022
Reflection based (Dictionary, CKRecord, NSManagedObject, Realm, JSON and XML) object mapping with extensions for Alamofire and Moya with RxSwift or ReactiveSwift

EVReflection General information At this moment the master branch is tested with Swift 4.2 and 5.0 beta If you want to continue using EVReflection in

Edwin Vermeer 964 Dec 14, 2022
A fast, convenient and nonintrusive conversion framework between JSON and model. Your model class doesn't need to extend any base class. You don't need to modify any model file.

MJExtension A fast, convenient and nonintrusive conversion framework between JSON and model. 转换速度快、使用简单方便的字典转模型框架 ?? ✍??Release Notes: more details Co

M了个J 8.5k Jan 3, 2023
Elevate is a JSON parsing framework that leverages Swift to make parsing simple, reliable and composable

Elevate is a JSON parsing framework that leverages Swift to make parsing simple, reliable and composable. Elevate should no longer be used for

Nike Inc. 611 Oct 23, 2022
HandyJSON is a framework written in Swift which to make converting model objects to and from JSON easy on iOS.

HandyJSON To deal with crash on iOS 14 beta4 please try version 5.0.3-beta HandyJSON is a framework written in Swift which to make converting model ob

Alibaba 4.1k Dec 29, 2022
ObjectMapper is a framework written in Swift that makes it easy for you to convert your model objects to and from JSON.

ObjectMapper is a framework written in Swift that makes it easy for you to convert your model objects (classes and structs) to and from J

Tristan Himmelman 9k Jan 2, 2023
Swift/Obj-C HTTP framework with a focus on REST and JSON

Now Archived and Forked PMHTTP will not be maintained in this repository going forward. Please use, create issues on, and make PRs to the fork of PHMT

Postmates Inc. 509 Sep 4, 2022
Jay - Pure-Swift JSON parser & formatter. Fully streamable input and output. Linux & OS X ready.

Pure-Swift JSON parser & formatter. Fully streamable input and output. Linux & OS X ready. Replacement for NSJSONSerialization.

Danielle 132 Dec 5, 2021
Hassle-free JSON encoding and decoding in Swift

#JSONCodable Hassle-free JSON encoding and decoding in Swift Installation Simply add the following to your Cartfile and run carthage update: github "m

Matthew Cheok 605 Jun 29, 2022