{"id":1706,"url":"https://github.com/SBJson/SBJson","last_synced_at":"2025-08-02T04:32:24.360Z","repository":{"id":943987,"uuid":"721040","full_name":"SBJson/SBJson","owner":"SBJson","description":"This framework implements a strict JSON parser and generator in Objective-C.","archived":false,"fork":false,"pushed_at":"2024-07-22T23:15:52.000Z","size":4780,"stargazers_count":3728,"open_issues_count":1,"forks_count":687,"subscribers_count":153,"default_branch":"trunk","last_synced_at":"2024-12-01T06:34:11.676Z","etag":null,"topics":["carthage","chunk","json","objective-c","parsing","sbjson"],"latest_commit_sha":null,"homepage":"","language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"osiloke/mezzanine_widgets","license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SBJson.png","metadata":{"files":{"readme":"README.md","changelog":"NEWS.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2010-06-14T22:02:16.000Z","updated_at":"2024-11-15T15:04:36.000Z","dependencies_parsed_at":"2022-08-08T19:00:01.751Z","dependency_job_id":"ed842cf7-24e1-4528-ae9c-bf09200e1b79","html_url":"https://github.com/SBJson/SBJson","commit_stats":{"total_commits":1070,"total_committers":51,"mean_commits":"20.980392156862745","dds":0.094392523364486,"last_synced_commit":"5f44fb51867316cda03585959154bed17011577e"},"previous_names":["stig/json-framework"],"tags_count":44,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SBJson%2FSBJson","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SBJson%2FSBJson/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SBJson%2FSBJson/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SBJson%2FSBJson/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SBJson","download_url":"https://codeload.github.com/SBJson/SBJson/tar.gz/refs/heads/trunk","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228439108,"owners_count":17920018,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["carthage","chunk","json","objective-c","parsing","sbjson"],"created_at":"2024-01-05T20:15:53.859Z","updated_at":"2024-12-06T08:31:30.221Z","avatar_url":"https://github.com/SBJson.png","language":"Objective-C","readme":"# SBJson 5\n\nChunk-based JSON parsing and generation in Objective-C.\n\n[![CircleCI](https://circleci.com/gh/SBJson/SBJson.svg?style=svg)](https://circleci.com/gh/SBJson/SBJson)\n[![Project Status: Inactive - The project has reached a stable, usable state but is no longer being actively developed; support/maintenance will be provided as time allows.](http://www.repostatus.org/badges/0.1.0/inactive.svg)](http://www.repostatus.org/#inactive)\n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n\n# Overview\n\nSBJson's number one feature is stream/chunk-based operation. Feed the parser one or\nmore chunks of UTF8-encoded data and it will call a block you provide with each\nroot-level document or array. Or, optionally, for each top-level entry in each\nroot-level array.\n\nWith this you can reduce the apparent latency for each\ndownload/parse cycle of documents over a slow connection. You can start\nparsing *and return chunks of the parsed document* before the full document\nhas downloaded. You can also parse massive documents bit by bit so you\ndon't have to keep them all in memory.\n\nSBJson maps JSON types to Objective-C types in the following way:\n\n| JSON Type | Objective-C Type                |\n|-----------|---------------------------------|\n| null      | NSNull                          |\n| string    | NSString                        |\n| array     | NSMutableArray                  |\n| object    | NSMutableDictionary             |\n| true      | -[NSNumber numberWithBool: YES] |\n| false     | -[NSNumber numberWithBool: NO]  |\n| number    | NSNumber                        |\n\n- Booleans roundtrip properly even though Objective-C doesn't have a\n  dedicated class for boolean values.\n- Integers use either `long long` or `unsigned long long` if they fit,\n  to avoid rounding errors.  For all other numbers we use the `double`\n  type, with all the potential rounding errors that entails.\n\n## \"Plain\" Chunk Based Parsing\n\nFirst define a simple block \u0026 an error handler. (These are just minimal\nexamples. You should strive to do something better that makes sense in your\napplication!)\n\n```objc\nSBJson5ValueBlock block = ^(id v, BOOL *stop) {\n    BOOL isArray = [v isKindOfClass:[NSArray class]];\n    NSLog(@\"Found: %@\", isArray ? @\"Array\" : @\"Object\");\n};\n\nSBJson5ErrorBlock eh = ^(NSError* err) {\n    NSLog(@\"OOPS: %@\", err);\n    exit(1);\n};\n```\n\nThen create a parser and add data to it:\n\n```objc\nid parser = [SBJson5Parser parserWithBlock:block\n                              errorHandler:eh];\n\nid data = [@\"[true,\" dataWithEncoding:NSUTF8StringEncoding];\n[parser parse:data]; // returns SBJson5ParserWaitingForData\n\n// block is not called yet...\n\n// ok, now we add another value and close the array\n\ndata = [@\"false]\" dataWithEncoding:NSUTF8StringEncoding];\n[parser parse:data]; // returns SBJson5ParserComplete\n\n// the above -parse: method calls your block before returning.\n```\n\nAlright! Now let's look at something slightly more interesting.\n\n## Handling multiple documents\n\nThis is useful for something like Twitter's feed, which gives you one JSON\ndocument per line. Here is an example of parsing many consequtive JSON\ndocuments, where your block will be called once for each document:\n\n```objc\nid parser = [SBJson5Parser multiRootParserWithBlock:block\n                                       errorHandler:eh];\n\n// Note that this input contains multiple top-level JSON documents\nid data = [@\"[]{}\" dataWithEncoding:NSUTF8StringEncoding];\n[parser parse:data];\n[parser parse:data];\n```\n\nThe above example will print:\n\n```\nFound: Array\nFound: Object\nFound: Array\nFound: Object\n```\n\n## Unwrapping a gigantic top-level array\n\nOften you won't have control over the input you're parsing, so can't use a\nmultiRootParser. But, all is not lost: if you are parsing a long array you can\nget the same effect by using an unwrapRootArrayParser:\n\n```objc\nid parser = [SBJson5Parser unwrapRootArrayParserWithBlock:block\n                                             errorHandler:eh];\n\n// Note that this input contains A SINGLE top-level document\nid data = [@\"[[],{},[],{}]\" dataWithEncoding:NSUTF8StringEncoding];\n[parser parse:data];\n```\n\n## Other features\n\n* For safety there is a max nesting level for all input. This defaults to 32,\n  but is configurable.\n* The writer can sort dictionary keys so output is consistent across writes.\n* The writer can create human-readable output, with newlines and indents.\n* You can install SBJson v3, v4 and v5 side-by-side in the same application.\n  (This is possible because all classes \u0026 public symbols contains the major\n  version number.)\n\n## A word of warning\n\nStream based parsing does mean that you lose some of the correctness\nverification you would have with a parser that considered the entire input\nbefore returning an answer. It is technically possible to have some parts of a\ndocument returned *as if they were correct* but then encounter an error in a\nlater part of the document. You should keep this in mind when considering\nwhether it would suit your application.\n\n# American Fuzzy Lop\n\nI've run [AFL][] on the sbjson binary for over 24 hours, with no crashes\nfound. (I cannot reproduce the hangs reported when attempting to parse them\nmanually.)\n\n[AFL]: http://lcamtuf.coredump.cx/afl/\n\n```\n                       american fuzzy lop 2.35b (sbjson)\n\n┌─ process timing ─────────────────────────────────────┬─ overall results ─────┐\n│        run time : 1 days, 0 hrs, 45 min, 26 sec      │  cycles done : 2      │\n│   last new path : 0 days, 0 hrs, 5 min, 24 sec       │  total paths : 555    │\n│ last uniq crash : none seen yet                      │ uniq crashes : 0      │\n│  last uniq hang : 0 days, 2 hrs, 11 min, 43 sec      │   uniq hangs : 19     │\n├─ cycle progress ────────────────────┬─ map coverage ─┴───────────────────────┤\n│  now processing : 250* (45.05%)     │    map density : 0.70% / 1.77%         │\n│ paths timed out : 0 (0.00%)         │ count coverage : 3.40 bits/tuple       │\n├─ stage progress ────────────────────┼─ findings in depth ────────────────────┤\n│  now trying : auto extras (over)    │ favored paths : 99 (17.84%)            │\n│ stage execs : 603/35.6k (1.70%)     │  new edges on : 116 (20.90%)           │\n│ total execs : 20.4M                 │ total crashes : 0 (0 unique)           │\n│  exec speed : 481.9/sec             │   total hangs : 44 (19 unique)         │\n├─ fuzzing strategy yields ───────────┴───────────────┬─ path geometry ────────┤\n│   bit flips : 320/900k, 58/900k, 5/899k             │    levels : 8          │\n│  byte flips : 0/112k, 4/112k, 3/112k                │   pending : 385        │\n│ arithmetics : 66/6.24M, 0/412k, 0/35                │  pend fav : 1          │\n│  known ints : 5/544k, 0/3.08M, 0/4.93M              │ own finds : 554        │\n│  dictionary : 0/0, 0/0, 29/1.83M                    │  imported : n/a        │\n│       havoc : 64/300k, 0/0                          │ stability : 100.00%    │\n│        trim : 45.19%/56.5k, 0.00%                   ├────────────────────────┘\n^C────────────────────────────────────────────────────┘             [cpu: 74%]\n\n+++ Testing aborted by user +++\n[+] We're done here. Have a nice day!\n```\n\n# API Documentation\n\nPlease see the [API Documentation](http://cocoadocs.org/docsets/SBJson) for\nmore details.\n\n\n# Installation\n\n## CocoaPods\n\nThe preferred way to use SBJson is by using\n[CocoaPods](http://cocoapods.org/?q=sbjson). In your Podfile use:\n\n    pod 'SBJson', '~\u003e 5.0.0'\n\n## Carthage\n\nSBJson is compatible with _Carthage_. Follow the [Getting Started Guide for iOS](https://github.com/Carthage/Carthage#if-youre-building-for-ios-tvos-or-watchos).\n\n\tgithub \"SBJson/SBJson\" == 5.0.2\n\n## Bundle the source files\n\nAn alternative that I no longer recommend is to copy all the source files (the\ncontents of the `Classes` folder) into your own Xcode project.\n\n# Examples\n\n* https://github.com/SBJson/ChunkedDelivery - a toy example showing how one can\n  use `NSURLSessionDataDelegate` to do chunked delivery.\n* https://github.com/SBJson/DisplayPretty - a very brief example using SBJson 4\n  to reflow JSON on OS X.\n\n# Support\n\n* Review (or create) StackOverflow questions [tagged with\n  `SBJson`](http://stackoverflow.com/questions/tagged/sbjson) if you\n  have questions about how to use the library.\n* Use the [issue tracker](http://github.com/SBJson/SBJson/issues) if you\n  have found a bug.\n* I regret I'm only able to support the current major release.\n\n## Philosophy on backwards compatibility\n\nSBJson practice [Semantic Versioning](https://semver.org/), which\nmeans we do not break the API in major releases. If something requires\na backwards-incompatible change, we release a new major version.\n(Hence why a library of less than 1k lines has more major versions\nthan Emacs.)\n\nI also try support a gradual migration from one major version to the\nother by allowing the last three major versions to co-exist in the\nsame app without conflicts. The way to do this is putting the major\nversion number in all the library's symbols and file names. So if v6\never comes out, the `SBJson5Parser` class would become\n`SBJson6Parser`, etc.\n\n# License\n\nBSD. See [LICENSE](LICENSE) for details.\n","funding_links":[],"categories":["Parsing","Libraries","JSON","Objective-C","sbjson"],"sub_categories":["JSON"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSBJson%2FSBJson","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FSBJson%2FSBJson","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSBJson%2FSBJson/lists"}