Tuesday, September 17, 2019 [Tweets] [Favorites]

Breaking the NSData.description Contract

Mattt Thompson (tweet via Cédric Luthi):

iOS 13 changes the format of descriptions for Foundation objects, including NSData:

// iOS 12
(deviceToken as NSData).description // "<965b251c 6cb1926d e3cb366f dfb16ddd e6b9086a 8a3cac9e 5f857679 376eab7C>"

// iOS 13
(deviceToken as NSData).description // "{length = 32, bytes = 0x965b251c 6cb1926d e3cb366f dfb16ddd ... 5f857679 376eab7c }"

Whereas previously, you could coerce NSData to spill its entire contents by converting it into a String, it now reports its length and a truncated summary of its internal bytes.

[…]

Was Apple irresponsible in making this particular change?

No, not really — developers shouldn’t have relied on a specific format for an object’s description.

The documentation promises—still, as of this writing—that description returns:

A string that contains a hexadecimal representation of the data object’s contents in a property list format.

Perhaps it would be a mistake to rely on the exact format of the string, e.g. where the spaces are inserted. But, clearly, it is supposed to contain the entire data’s contents, in a format that can be reconstituted by the property list API. That is no longer the case, and the fault for any resulting breakage lies with Apple, not with developers who were relying on the API to do what it said it would do.

Apple hasn’t explained why it made the change, or even documented it in the release notes. In fact, there don’t even seem to be Foundation release notes yet.

Previously:

Update (2019-09-17): Joe Groff:

It doesn’t break anything until you build with Xcode 11. The new behavior is based on the linked SDK version, so existing binaries keep working. If you want to upgrade your Xcode, you need to fix your code, though

Cédric Luthi:

Haha, I remember thinking “why did they introduce -UUIDString and not just used -description” for that purpose. Turns out, Apple thought about it too and changed the implementation of -[NSUUID description] in recent OS versions.

Seems like they should have provided a similar replacement on NSData for people relying on the old format.

Update (2019-09-18): Peter Steinberger:

Took the time to decompile [NSData description] on iOS 13 GMv2 and can verify that Apple did the sensible thing here: output only changes if linked SDK is > 12. Existing apps continue to work (forwards to debugDescription) once you adopt Xcode 11 they need to be fixed tho.

See also: this thread.

2 Comments

Why are people making comments about abuse of API or "fix your code" when this has been documented forever? ISTR someone (Andrew Stone or Bill Bumgarner?) pointing out that this was a design feature in some old Cocoa example code. Gratuitously breaking a decades-old documentation contract and then blaming developers is incredible.

[…] Another breaking change to an API that’s been around since Mac OS X 10.10, without updating the documentation or mentioning the change in a release note: […]

Stay up-to-date by subscribing to the Comments RSS Feed for this post.

Leave a Comment