NSDictionary
NSData
iOS development
Swift programming
data conversion

How can I convert NSDictionary to NSData and vice versa?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Converting NSDictionary to NSData really means serializing a dictionary into bytes, and converting NSData back means deserializing those bytes into a dictionary again. The correct method depends on the format you want, usually JSON or property list.

The important rule is that not every dictionary can be serialized by every format. The dictionary contents must be compatible with the serializer you choose.

JSON Is the Most Common Choice

If the dictionary contains JSON-compatible values such as strings, numbers, arrays, dictionaries, booleans, and NSNull, JSONSerialization is usually the right tool.

Swift example:

swift
1import Foundation
2
3let dictionary: NSDictionary = [
4    "name": "Alice",
5    "age": 30,
6    "roles": ["admin", "editor"]
7]
8
9let data = try JSONSerialization.data(withJSONObject: dictionary, options: [])
10print(data as NSData)

And to convert the Data back:

swift
1import Foundation
2
3let dictionary: NSDictionary = [
4    "name": "Alice",
5    "age": 30
6]
7
8let data = try JSONSerialization.data(withJSONObject: dictionary, options: [])
9let object = try JSONSerialization.jsonObject(with: data, options: [])
10
11if let result = object as? NSDictionary {
12    print(result)
13}

That is the usual answer when you are preparing data for a network request or parsing JSON-like payloads.

Objective-C Version

If you are working in Objective-C with the exact NSDictionary and NSData types from the title, the same logic applies:

objective-c
1NSDictionary *dictionary = @{
2    @"name": @"Alice",
3    @"age": @30
4};
5
6NSError *error = nil;
7NSData *data = [NSJSONSerialization dataWithJSONObject:dictionary
8                                               options:0
9                                                 error:&error];
10
11if (data) {
12    NSLog(@"Serialized data length: %lu", (unsigned long)data.length);
13}

Deserialization:

objective-c
1NSError *error = nil;
2NSDictionary *dictionary = @{
3    @"name": @"Alice",
4    @"age": @30
5};
6
7NSData *data = [NSJSONSerialization dataWithJSONObject:dictionary
8                                               options:0
9                                                 error:&error];
10
11id object = [NSJSONSerialization JSONObjectWithData:data
12                                            options:0
13                                              error:&error];
14
15if ([object isKindOfClass:[NSDictionary class]]) {
16    NSDictionary *decoded = (NSDictionary *)object;
17    NSLog(@"%@", decoded[@"name"]);
18}

This is the most direct Foundation-based approach.

When to Use Property Lists Instead

If the data is intended for Apple-only persistence or settings-like storage, property list serialization can be a better fit. Property lists support Foundation object graphs such as strings, numbers, dates, arrays, dictionaries, and data objects.

Swift example:

swift
1import Foundation
2
3let dictionary: NSDictionary = [
4    "username": "alice",
5    "loginCount": 5
6]
7
8let data = try PropertyListSerialization.data(
9    fromPropertyList: dictionary,
10    format: .xml,
11    options: 0
12)
13
14let object = try PropertyListSerialization.propertyList(
15    from: data,
16    options: [],
17    format: nil
18)
19
20if let result = object as? NSDictionary {
21    print(result)
22}

Use this when you want a property-list format rather than JSON, for example in Apple-specific storage or configuration use cases.

Bridging Between NSDictionary and Swift Types

In current Swift code, you often work with [String: Any] and Data rather than NSDictionary and NSData. The bridging is usually automatic:

swift
let swiftDict: [String: Any] = ["enabled": true, "count": 3]
let nsDict = swiftDict as NSDictionary

And:

swift
let data: Data = Data([1, 2, 3])
let nsData = data as NSData

So even if the API title uses the Objective-C class names, the real serialization workflow in Swift is usually dictionary to Data and back.

Format Consistency Matters

If you encode as JSON, decode as JSON. If you encode as a property list, decode as a property list. The bytes do not carry enough context for Foundation to magically guess your intent.

This sounds obvious, but many bugs come from treating “bytes from a dictionary” as a generic concept when the actual format was never stated clearly.

Common Pitfalls

One common mistake is trying to serialize objects that are not valid JSON values, such as arbitrary custom classes. JSONSerialization only accepts JSON-compatible types.

Another mistake is assuming any NSData can be cast directly to NSDictionary. Raw bytes are not a dictionary until they are decoded using the same format that produced them.

It is also easy to ignore error handling. Serialization failures are common when the object graph contains unsupported values, so do and catch or NSError checks matter.

Finally, if you only need local secure persistence of custom objects, Codable or keyed archiving may be a better design than manually round-tripping through NSDictionary.

Summary

  • Convert NSDictionary to NSData by serializing it, usually with JSONSerialization or PropertyListSerialization.
  • Convert NSData back by deserializing with the matching format.
  • JSON is the usual choice for network-friendly dictionary data.
  • Property lists are useful for Apple-specific storage and configuration formats.
  • Make sure the dictionary contents are compatible with the serializer you choose.

Course illustration
Course illustration

All Rights Reserved.