{"id":18491,"date":"2017-07-28T14:44:16","date_gmt":"2017-07-28T18:44:16","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=18491"},"modified":"2019-01-18T10:30:17","modified_gmt":"2019-01-18T15:30:17","slug":"a-binary-coder-for-swift","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2017\/07\/28\/a-binary-coder-for-swift\/","title":{"rendered":"A Binary Coder for Swift"},"content":{"rendered":"<p><a href=\"https:\/\/mikeash.com\/pyblog\/friday-qa-2017-07-28-a-binary-coder-for-swift.html\">Mike Ash<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mikeash.com\/pyblog\/friday-qa-2017-07-28-a-binary-coder-for-swift.html\">\n<p>This coder serializes fields by writing them out sequentially as raw bytes, with no metadata.<\/p>\n<p>[&#8230;]<\/p>\n<p>Now we can see why I implemented <code>BinaryEncoder<\/code>&rsquo;s <code>encode<\/code> method with a big <code>switch<\/code> statement instead of using separate implementations for all of the various supported types. Overloaded methods are resolved at compile time based on the static type that&rsquo;s available at the call site. The above call to <code>encoder.encode(value)<\/code> will always call <code>func encode(_ encodable: Encodable)<\/code> even if the actual value passed in is, say, a <code>Double<\/code> or a <code>Bool<\/code>. In order to allow for this simple wrapper, the implementation in <code>BinaryEncoder<\/code> has to work with a single entry point, which means it needs to be a big <code>switch<\/code> statement.<\/p>\n<p>[&#8230;]<\/p>\n<p>Swift&rsquo;s new <code>Codable<\/code> protocols are a welcome addition to the language to eliminate a lot of boilerplate code. It&rsquo;s flexible enough to make it straightforward to use\/abuse it for things well beyond JSON and property list parsing. Unsophisticated binary formats such as this are not often called for, but they have their uses, and it&rsquo;s interesting to see how <code>Codable<\/code> can be used for something so different from the built-in facilities. The <code>Encoder<\/code> and <code>Decoder<\/code> protocols are large, but judicious use of generics can cut down a lot of the repetitive code, and implementation is relatively simple in the end.<\/p>\n<\/blockquote>\n\n<p>See also: <a href=\"https:\/\/gist.github.com\/phausler\/6c61343a609aeeb9a8f890f1fe2acc17\">HashingSingleValueEncodingContainer<\/a>, <a href=\"https:\/\/gist.github.com\/sjoerdvisscher\/255a0ea58706f63ed84958b6f3c46b82\">MinimalDecoder<\/a> (via <a href=\"https:\/\/twitter.com\/stephencelis\/status\/887008117346750472\">Stephen Celis<\/a>).<\/p>\n<p>Previously: <a href=\"https:\/\/mjtsai.com\/blog\/2017\/07\/14\/swift-codable\/\">Swift.Codable<\/a>.<\/p>\n\n<p>Update (2017-07-31): See also: <a href=\"https:\/\/news.ycombinator.com\/item?id=14880716\">Hacker News<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>Mike Ash: This coder serializes fields by writing them out sequentially as raw bytes, with no metadata. [&#8230;] Now we can see why I implemented BinaryEncoder&rsquo;s encode method with a big switch statement instead of using separate implementations for all of the various supported types. Overloaded methods are resolved at compile time based on the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"2019-01-18T15:30:20Z","apple_news_api_id":"201652c0-738c-4abd-b9af-4320d56b3718","apple_news_api_modified_at":"2019-01-18T15:30:20Z","apple_news_api_revision":"AAAAAAAAAAD\/\/\/\/\/\/\/\/\/\/w==","apple_news_api_share_url":"https:\/\/apple.news\/AIBZSwHOMSr25r0Mg1Ws3GA","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[31,1472,30,1529,71,1774,901],"class_list":["post-18491","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-ios","tag-ios-11","tag-mac","tag-macos-10-13","tag-programming","tag-swift-codable","tag-swift-programming-language"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/18491","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=18491"}],"version-history":[{"count":2,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/18491\/revisions"}],"predecessor-version":[{"id":18504,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/18491\/revisions\/18504"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=18491"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=18491"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=18491"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}