{"id":26629,"date":"2019-09-17T16:10:07","date_gmt":"2019-09-17T20:10:07","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=26629"},"modified":"2019-12-23T16:34:01","modified_gmt":"2019-12-23T21:34:01","slug":"breaking-the-nsdata-description-contract","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2019\/09\/17\/breaking-the-nsdata-description-contract\/","title":{"rendered":"Breaking the NSData.description Contract"},"content":{"rendered":"<p><a href=\"https:\/\/nshipster.com\/apns-device-tokens\/\">Mattt Thompson<\/a> (<a href=\"https:\/\/twitter.com\/NSHipster\/status\/1173657903070203905\">tweet<\/a> via <a href=\"https:\/\/twitter.com\/0xced\/status\/1173705574598553600\">C&eacute;dric Luthi<\/a>):<\/p>\n<blockquote cite=\"https:\/\/nshipster.com\/apns-device-tokens\/\">\n<p>iOS 13 changes the format of descriptions for Foundation objects, including NSData:<\/p>\n<pre>\/\/ iOS 12\n(deviceToken as NSData).description \/\/ \"&lt;965b251c 6cb1926d e3cb366f dfb16ddd e6b9086a 8a3cac9e 5f857679 376eab7C&gt;\"\n\n\/\/ iOS 13\n(deviceToken as NSData).description \/\/ \"{length = 32, bytes = 0x965b251c 6cb1926d e3cb366f dfb16ddd ... 5f857679 376eab7c }\"<\/pre>\n<p>Whereas previously, you could coerce <code>NSData<\/code> to spill its entire contents by converting it into a <code>String<\/code>, it now reports its length and a truncated summary of its internal bytes.<\/p>\n<p>[&#8230;]<\/p>\n<p>Was Apple irresponsible in making this particular change?<\/p>\n<p>No, not really &mdash; developers shouldn&rsquo;t have relied on a specific format for an object&rsquo;s <a href=\"https:\/\/developer.apple.com\/documentation\/objectivec\/nsobjectprotocol\/1418746-description\"><code>description<\/code><\/a>.<\/p>\n<\/blockquote>\n<p>The <a href=\"https:\/\/developer.apple.com\/documentation\/foundation\/nsdata\/1412579-description\">documentation<\/a> promises&mdash;still, as of this writing&mdash;that <code>description<\/code> returns:<\/p>\n<blockquote cite=\"https:\/\/developer.apple.com\/documentation\/foundation\/nsdata\/1412579-description\"><p>A string that contains a hexadecimal representation of the data object&rsquo;s contents in a property list format.<\/p><\/blockquote>\n<p>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&rsquo;s contents, in a format that can be reconstituted by the <a href=\"https:\/\/developer.apple.com\/documentation\/foundation\/nsstring\/1413115-propertylist\">property list API<\/a>. 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.<\/p>\n<p>Apple hasn&rsquo;t explained why it made the change, or even documented it in the <a href=\"https:\/\/developer.apple.com\/documentation\/macos_release_notes\/macos_catalina_10_15_beta_8_release_notes\">release notes<\/a>. In fact, there don&rsquo;t even seem to be Foundation release notes yet.<\/p>\n\n<p>Previously:<\/p>\n<ul>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2019\/06\/06\/macos-10-15-beta\/\">macOS 10.15 Beta<\/a><\/li>\n<\/ul>\n\n<p>Update (2019-09-17): <a href=\"https:\/\/twitter.com\/jckarter\/status\/1174043347947679744\">Joe Groff<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/jckarter\/status\/1174043347947679744\">\n<p>It doesn&rsquo;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<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/twitter.com\/0xced\/status\/1174046204247859200\">C&eacute;dric Luthi<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/0xced\/status\/1174046204247859200\"><p>Haha, I remember thinking &ldquo;why did they introduce <code>-UUIDString<\/code> and not just used <code>-description<\/code>&rdquo; for that purpose. Turns out, Apple thought about it too and changed the implementation of <code>-[NSUUID description]<\/code> in recent OS versions.<\/p><\/blockquote>\n\n<p>Seems like they should have provided a similar replacement on <code>NSData<\/code> for people relying on the old format.<\/p>\n\n<p id=\"breaking-the-nsdata-description-contract-update-2019-09-18\">Update (2019-09-18): <a href=\"https:\/\/twitter.com\/steipete\/status\/1174111017900503040\">Peter Steinberger<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/steipete\/status\/1174111017900503040\">\n<p>Took the time to decompile <code>[NSData description]<\/code> on iOS 13 GMv2 and can verify that Apple did the sensible thing here: output only changes if linked SDK is &gt; 12. Existing apps continue to work (forwards to debugDescription) once you adopt Xcode 11 they need to be fixed tho.<\/p>\n<\/blockquote>\n\n<p>See also: <a href=\"https:\/\/twitter.com\/rosyna\/status\/1174130622219968512\">this<\/a> <a href=\"https:\/\/twitter.com\/gpdawson\/status\/1174132716855390209\">thread<\/a>.<\/p>\n\n<p id=\"breaking-the-nsdata-description-contract-update-2019-12-23\">Update (2019-12-23): <a href=\"https:\/\/twitter.com\/iamevltwin\/status\/1186045208384954370\">Sarah Edwards<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/iamevltwin\/status\/1186045208384954370\">\n<p>Anyone know how to make Xcode\/plutil to stop truncating BLOBs? Seems to have started with macOS 10.15. Previously could see entire BLOB and export to hex editor, etc. Would prefer not to have to use 3rd party or conversion. This is driving me crazy.<\/p>\n<\/blockquote>\n\n<p>This seems to be consequence of the change to <code>NSData<\/code>.<\/p>","protected":false},"excerpt":{"rendered":"<p>Mattt Thompson (tweet via C&eacute;dric Luthi): iOS 13 changes the format of descriptions for Foundation objects, including NSData: \/\/ iOS 12 (deviceToken as NSData).description \/\/ \"&lt;965b251c 6cb1926d e3cb366f dfb16ddd e6b9086a 8a3cac9e 5f857679 376eab7C&gt;\" \/\/ iOS 13 (deviceToken as NSData).description \/\/ \"{length = 32, bytes = 0x965b251c 6cb1926d e3cb366f dfb16ddd ... 5f857679 376eab7c }\" Whereas previously, [&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-09-17T20:10:10Z","apple_news_api_id":"e7a39390-ddc3-40df-a928-13e5d4728bdb","apple_news_api_modified_at":"2019-12-23T21:34:06Z","apple_news_api_revision":"AAAAAAAAAAAAAAAAAAAABQ==","apple_news_api_share_url":"https:\/\/apple.news\/A56OTkN3DQN-pKBPl1HKL2w","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":[69,164,31,1667,30,1666,71,226],"class_list":["post-26629","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-cocoa","tag-documentation","tag-ios","tag-ios-13","tag-mac","tag-macos-10-15","tag-programming","tag-xcode"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/26629","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=26629"}],"version-history":[{"count":7,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/26629\/revisions"}],"predecessor-version":[{"id":27671,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/26629\/revisions\/27671"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=26629"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=26629"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=26629"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}