I myself am not a fan of using the third library, usually in projects I always try to write in a pure library. If you are the same person, continue reading .
To be able to parse JSON
in Swift
until now I know that there are two libraries that many users are SwiftyJSON
and ObjectMapper
but if you do not like installing via Cocoapods or Carthage then use the apple provided, that is Codable
Codable is an alias of two protocols: Decodable
& Encodable
, Codable protocol is used to convert JSON data object into a class or struct in Swift, this process is called Decoding because JSON data is decoded into a format that Swift understands. Codable can also encode (encoding) Swift objects into JSON.
Swift Codable basic
We will go into the first example of Swift Codable, the goal will be to convert the following JSON into Swift object (struct)
1 2 3 4 5 6 7 8 9 | <span class="token keyword">let</span> jsonString <span class="token operator">=</span> <span class="token string">""</span> " <span class="token punctuation">{</span> <span class="token string">"first_name"</span> <span class="token punctuation">:</span> <span class="token string">"Ngo"</span> <span class="token punctuation">,</span> <span class="token string">"last_name"</span> <span class="token punctuation">:</span> <span class="token string">"Viet Anh"</span> <span class="token punctuation">,</span> <span class="token string">"country"</span> <span class="token punctuation">:</span> <span class="token string">"Viet Nam"</span> <span class="token punctuation">,</span> <span class="token string">"age"</span> <span class="token punctuation">:</span> <span class="token number">20</span> <span class="token punctuation">}</span> <span class="token string">""</span> " |
Making:
For simple JSON forms like this, just create a struct conform Codable protocol for accuracy, then use JSONDecoder () to decode the instance. Note: If no encode is needed, just conforming to the Decodable protocol is sufficient.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <span class="token keyword">struct</span> <span class="token builtin">Person</span> <span class="token punctuation">:</span> <span class="token builtin">Codable</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> first_name <span class="token punctuation">:</span> <span class="token builtin">String</span> <span class="token operator">=</span> <span class="token string">""</span> <span class="token keyword">var</span> last_name <span class="token punctuation">:</span> <span class="token builtin">String</span> <span class="token operator">=</span> <span class="token string">""</span> <span class="token keyword">var</span> country <span class="token punctuation">:</span> <span class="token builtin">String</span> <span class="token operator">=</span> <span class="token string">""</span> <span class="token keyword">var</span> age <span class="token punctuation">:</span> <span class="token builtin">Int</span> <span class="token operator">=</span> <span class="token number">0</span> <span class="token punctuation">}</span> <span class="token comment">// Convert json string to data</span> <span class="token keyword">var</span> data <span class="token operator">=</span> <span class="token function">Data</span> <span class="token punctuation">(</span> jsonString <span class="token punctuation">.</span> utf8 <span class="token punctuation">)</span> <span class="token keyword">let</span> decoder <span class="token operator">=</span> <span class="token function">JSONDecoder</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token comment">// Decode json with dictionary</span> <span class="token keyword">let</span> personEntity <span class="token operator">=</span> <span class="token keyword">try</span> <span class="token operator">?</span> decoder <span class="token punctuation">.</span> <span class="token function">decode</span> <span class="token punctuation">(</span> <span class="token builtin">Person</span> <span class="token punctuation">.</span> <span class="token keyword">self</span> <span class="token punctuation">,</span> from <span class="token punctuation">:</span> data <span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token keyword">let</span> personEntity <span class="token operator">=</span> personEntity <span class="token punctuation">{</span> <span class="token function">print</span> <span class="token punctuation">(</span> personEntity <span class="token punctuation">)</span> <span class="token comment">/// Person(first_name: "Ngo", last_name: "Viet Anh", country: "Viet Nam", age: 20)</span> <span class="token punctuation">}</span> |
For array form like this
1 2 3 4 5 6 7 8 9 10 11 12 13 | [{ "first_name": "Ngo", "last_name": "Viet Anh", "country": "Viet Nam", "age": 20 }, { "first_name": "Dang", "last_name": "Thanh Dat", "country": "Viet Nam", "age": 69 }] |
Then just add the array where the decode is
1 2 | <span class="token keyword">let</span> personEntity <span class="token operator">=</span> <span class="token keyword">try</span> <span class="token operator">?</span> decoder <span class="token punctuation">.</span> <span class="token function">decode</span> <span class="token punctuation">(</span> <span class="token punctuation">[</span> <span class="token builtin">Person</span> <span class="token punctuation">]</span> <span class="token punctuation">.</span> <span class="token keyword">self</span> <span class="token punctuation">,</span> from <span class="token punctuation">:</span> data <span class="token punctuation">)</span> |
Swift Codable manual encode decode
For json like this
1 2 3 4 5 6 7 8 9 10 11 | <span class="token keyword">let</span> jsonString <span class="token operator">=</span> <span class="token string">""</span> " <span class="token punctuation">{</span> <span class="token string">"person_detail"</span> <span class="token punctuation">:</span> <span class="token punctuation">{</span> <span class="token string">"first_name"</span> <span class="token punctuation">:</span> <span class="token string">"Ngo"</span> <span class="token punctuation">,</span> <span class="token string">"last_name"</span> <span class="token punctuation">:</span> <span class="token string">"Viet Anh"</span> <span class="token punctuation">,</span> <span class="token string">"country"</span> <span class="token punctuation">:</span> <span class="token string">"Viet Nam"</span> <span class="token punctuation">,</span> <span class="token string">"age"</span> <span class="token punctuation">:</span> <span class="token number">20</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token string">""</span> " |
To handle then we do the following
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <span class="token keyword">struct</span> <span class="token builtin">PersonData</span> <span class="token punctuation">:</span> <span class="token builtin">Codable</span> <span class="token punctuation">{</span> <span class="token keyword">struct</span> <span class="token builtin">Person</span> <span class="token punctuation">:</span> <span class="token builtin">Codable</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> first_name <span class="token punctuation">:</span> <span class="token builtin">String</span> <span class="token operator">=</span> <span class="token string">""</span> <span class="token keyword">var</span> last_name <span class="token punctuation">:</span> <span class="token builtin">String</span> <span class="token operator">=</span> <span class="token string">""</span> <span class="token keyword">var</span> country <span class="token punctuation">:</span> <span class="token builtin">String</span> <span class="token operator">=</span> <span class="token string">""</span> <span class="token keyword">var</span> age <span class="token punctuation">:</span> <span class="token builtin">Int</span> <span class="token operator">=</span> <span class="token number">0</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> person_detail <span class="token punctuation">:</span> <span class="token builtin">Person</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> data <span class="token operator">=</span> <span class="token function">Data</span> <span class="token punctuation">(</span> jsonString <span class="token punctuation">.</span> utf8 <span class="token punctuation">)</span> <span class="token keyword">let</span> decoder <span class="token operator">=</span> <span class="token function">JSONDecoder</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token comment">// Decode json with dictionary</span> <span class="token keyword">let</span> personEntity <span class="token operator">=</span> <span class="token keyword">try</span> <span class="token operator">?</span> decoder <span class="token punctuation">.</span> <span class="token function">decode</span> <span class="token punctuation">(</span> <span class="token builtin">PersonData</span> <span class="token punctuation">.</span> <span class="token keyword">self</span> <span class="token punctuation">,</span> from <span class="token punctuation">:</span> data <span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token keyword">let</span> personEntity <span class="token operator">=</span> personEntity <span class="token punctuation">{</span> <span class="token function">print</span> <span class="token punctuation">(</span> personEntity <span class="token punctuation">.</span> person_detail <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Swift Codable coding key
In most cases, the client will use the json format that the server has already defined, so json types of the above format may be encountered, but if Struct can be codable, the need to define properties as person_detail, first_name. This violates the coding convention of Swift. In this case we use the Coding key to map between the properties of Struct and the key of JSON.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <span class="token keyword">struct</span> <span class="token builtin">Person</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> firstName <span class="token punctuation">:</span> <span class="token builtin">String</span> <span class="token operator">=</span> <span class="token string">""</span> <span class="token keyword">var</span> lastName <span class="token punctuation">:</span> <span class="token builtin">String</span> <span class="token operator">=</span> <span class="token string">""</span> <span class="token keyword">var</span> country <span class="token punctuation">:</span> <span class="token builtin">String</span> <span class="token operator">=</span> <span class="token string">""</span> <span class="token keyword">var</span> age <span class="token punctuation">:</span> <span class="token builtin">Int</span> <span class="token operator">=</span> <span class="token number">0</span> <span class="token keyword">enum</span> <span class="token builtin">PersonKeys</span> <span class="token punctuation">:</span> <span class="token builtin">String</span> <span class="token punctuation">,</span> <span class="token builtin">CodingKey</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> person <span class="token operator">=</span> <span class="token string">"person_detail"</span> <span class="token punctuation">}</span> <span class="token keyword">enum</span> <span class="token builtin">PersonDetailKeys</span> <span class="token punctuation">:</span> <span class="token builtin">String</span> <span class="token punctuation">,</span> <span class="token builtin">CodingKey</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> firstName <span class="token operator">=</span> <span class="token string">"first_name"</span> <span class="token keyword">case</span> lastName <span class="token operator">=</span> <span class="token string">"last_name"</span> <span class="token keyword">case</span> country <span class="token keyword">case</span> age <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
To decode
1 2 3 4 5 6 7 8 9 10 11 12 13 | <span class="token keyword">extension</span> <span class="token builtin">Person</span> <span class="token punctuation">:</span> <span class="token builtin">Decodable</span> <span class="token punctuation">{</span> <span class="token keyword">init</span> <span class="token punctuation">(</span> from decoder <span class="token punctuation">:</span> <span class="token builtin">Decoder</span> <span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> personContainer <span class="token operator">=</span> <span class="token keyword">try</span> decoder <span class="token punctuation">.</span> <span class="token function">container</span> <span class="token punctuation">(</span> keyedBy <span class="token punctuation">:</span> <span class="token builtin">PersonKeys</span> <span class="token punctuation">.</span> <span class="token keyword">self</span> <span class="token punctuation">)</span> <span class="token keyword">let</span> personDetailContainer <span class="token operator">=</span> <span class="token keyword">try</span> personContainer <span class="token punctuation">.</span> <span class="token function">nestedContainer</span> <span class="token punctuation">(</span> keyedBy <span class="token punctuation">:</span> <span class="token builtin">PersonDetailKeys</span> <span class="token punctuation">.</span> <span class="token keyword">self</span> <span class="token punctuation">,</span> forKey <span class="token punctuation">:</span> <span class="token punctuation">.</span> person <span class="token punctuation">)</span> firstName <span class="token operator">=</span> <span class="token keyword">try</span> personDetailContainer <span class="token punctuation">.</span> <span class="token function">decode</span> <span class="token punctuation">(</span> <span class="token builtin">String</span> <span class="token punctuation">.</span> <span class="token keyword">self</span> <span class="token punctuation">,</span> forKey <span class="token punctuation">:</span> <span class="token punctuation">.</span> firstName <span class="token punctuation">)</span> lastName <span class="token operator">=</span> <span class="token keyword">try</span> personDetailContainer <span class="token punctuation">.</span> <span class="token function">decode</span> <span class="token punctuation">(</span> <span class="token builtin">String</span> <span class="token punctuation">.</span> <span class="token keyword">self</span> <span class="token punctuation">,</span> forKey <span class="token punctuation">:</span> <span class="token punctuation">.</span> lastName <span class="token punctuation">)</span> country <span class="token operator">=</span> <span class="token keyword">try</span> personDetailContainer <span class="token punctuation">.</span> <span class="token function">decode</span> <span class="token punctuation">(</span> <span class="token builtin">String</span> <span class="token punctuation">.</span> <span class="token keyword">self</span> <span class="token punctuation">,</span> forKey <span class="token punctuation">:</span> <span class="token punctuation">.</span> country <span class="token punctuation">)</span> age <span class="token operator">=</span> <span class="token keyword">try</span> personDetailContainer <span class="token punctuation">.</span> <span class="token function">decode</span> <span class="token punctuation">(</span> <span class="token builtin">Int</span> <span class="token punctuation">.</span> <span class="token keyword">self</span> <span class="token punctuation">,</span> forKey <span class="token punctuation">:</span> <span class="token punctuation">.</span> age <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
In case it is necessary to encode to send to the server then
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <span class="token keyword">extension</span> <span class="token builtin">Person</span> <span class="token punctuation">:</span> <span class="token builtin">Encodable</span> <span class="token punctuation">{</span> <span class="token keyword">func</span> <span class="token function">encode</span> <span class="token punctuation">(</span> to encoder <span class="token punctuation">:</span> <span class="token builtin">Encoder</span> <span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> personContainer <span class="token operator">=</span> encoder <span class="token punctuation">.</span> <span class="token function">container</span> <span class="token punctuation">(</span> keyedBy <span class="token punctuation">:</span> <span class="token builtin">PersonKeys</span> <span class="token punctuation">.</span> <span class="token keyword">self</span> <span class="token punctuation">)</span> <span class="token keyword">var</span> personDetailContainer <span class="token operator">=</span> personContainer <span class="token punctuation">.</span> <span class="token function">nestedContainer</span> <span class="token punctuation">(</span> keyedBy <span class="token punctuation">:</span> <span class="token builtin">PersonDetailKeys</span> <span class="token punctuation">.</span> <span class="token keyword">self</span> <span class="token punctuation">,</span> forKey <span class="token punctuation">:</span> <span class="token punctuation">.</span> person <span class="token punctuation">)</span> <span class="token keyword">try</span> personDetailContainer <span class="token punctuation">.</span> <span class="token function">encode</span> <span class="token punctuation">(</span> firstName <span class="token punctuation">,</span> forKey <span class="token punctuation">:</span> <span class="token punctuation">.</span> firstName <span class="token punctuation">)</span> <span class="token keyword">try</span> personDetailContainer <span class="token punctuation">.</span> <span class="token function">encode</span> <span class="token punctuation">(</span> lastName <span class="token punctuation">,</span> forKey <span class="token punctuation">:</span> <span class="token punctuation">.</span> lastName <span class="token punctuation">)</span> <span class="token keyword">try</span> personDetailContainer <span class="token punctuation">.</span> <span class="token function">encode</span> <span class="token punctuation">(</span> country <span class="token punctuation">,</span> forKey <span class="token punctuation">:</span> <span class="token punctuation">.</span> country <span class="token punctuation">)</span> <span class="token keyword">try</span> personDetailContainer <span class="token punctuation">.</span> <span class="token function">encodeIfPresent</span> <span class="token punctuation">(</span> age <span class="token punctuation">,</span> forKey <span class="token punctuation">:</span> <span class="token punctuation">.</span> age <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> encoder <span class="token operator">=</span> <span class="token function">JSONEncoder</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token comment">// Encode instance to Data</span> <span class="token keyword">if</span> <span class="token keyword">let</span> personEntity <span class="token operator">=</span> personEntity <span class="token punctuation">{</span> <span class="token keyword">let</span> personData <span class="token operator">=</span> <span class="token keyword">try</span> <span class="token operator">?</span> encoder <span class="token punctuation">.</span> <span class="token function">encode</span> <span class="token punctuation">(</span> personEntity <span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token keyword">let</span> personData <span class="token operator">=</span> personData <span class="token punctuation">{</span> <span class="token function">print</span> <span class="token punctuation">(</span> personData <span class="token punctuation">)</span> <span class="token comment">///91 bytes</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
It’s a bit long, but building yourself in this way is dangerous too
With the above hope you will understand and feel comfortable using Codable. The first article has many shortcomings, hope everyone helps.