This is my research notebook. I'm an OSX / iOS indie developer. After 8 years of Objective-C I really enjoy Swift nowadays. Trying to publish all my research on Development, Swift & other technologies here.
BENEDIKT TERHECHTE
Tue, 21 Jan 2014 #
I recently ran into an issue where a Mac App did lack an entitlement even though I had all entitlements properly set up in my account. I also had performed rigourous testing prior to submission, which made it even more worrisome as I had no idea how to proceed.
Since everything was running fine on my machine, and since the error in question was happening when users installed the app, I needed a way to figure out what happened to the binary right before Xcode submits it to the App Store.
If you happen to have such an issue, i.e. an Apple Maps or iCloud or Game Center or Keychain Sharing or In-App Purchase error that only happens on your customers system, there is indeed a way to debug this issue.
In Technical Note TN2265, Troubleshooting Push Notifications , Apple explains a very useful process that explains what to do in such situations as outlined above. In the 'Error Delegate Callback ' section, the document explains how you can export the App from the Organizer just as it would be submitted to the App Store, and how you can inspect the result in order to figure out whether all the correct entitlements are set:
Export the app as Mac Installer Package, using the same identity that you use when submitting to the Mac App Store
Locate the generated Pkg file in the Terminal
Run the following code in the Terminal
pkgutil --expand "YourApp.pkg" Expanded_pkg
open Expanded_pkg/com.yourcompany.yourapp/Payload
codesign -d --entitlements - "Expanded_pkg/com.yourcompany.yourapp/YourApp.app"
This will show you the list of entitlements that are included in your app upon submission to the App Store. This is a very useful thing to know, in fact so useful, that Apple writes, right below the process.
Note: This is a useful test to perform on your distribution builds before submitting them to the App Store.
Absolutely, it would also be great if such a Gem wasn't hidden in a page that just deals with Push Notification issues.
Related Articles
Wed, 10 Jan 2018 : Useful Optional Extensions Sun, 10 Dec 2017 : Patterns for Working With Associated Types Sun, 8 Oct 2017 : Taming SourceKitService for Less Xcode Memory Consumption Sat, 30 Sep 2017 : Value Types for Simple Difference Detection Fri, 15 Jul 2016 : Data in Swift 3 parsing a Doom WAD File Thu, 28 Apr 2016 : SwiftWatch Sat, 23 Apr 2016 : Raw value initializers for enums with associated types Thu, 14 Apr 2016 : Force optionals in multi-unwrapped "guard let" or "if let" Tue, 29 Mar 2016 : Three tips for concise Swift using the Guard statement Tue, 2 Feb 2016 : Hirundo: Comfortably follow Swift Mailing Lists on OSX Mon, 30 Nov 2015 : Reduce all the things Sat, 24 Oct 2015 : The Swift Reflection API and what you can do with it Sat, 17 Oct 2015 : Advanced & Practical Enum usage in Swift Thu, 20 Aug 2015 : Match Me if you can: Swift Pattern Matching in Detail. Fri, 19 Jun 2015 : Using try / catch in Swift with asynchronous closures Wed, 17 Jun 2015 : Generic method overloading by protocol in Swift Fri, 13 Jun 2014 : Swift optionals made simple Sun, 8 Jun 2014 : Creating a Swift syntax extension: the Lisp 'cond' function Tue, 21 Jan 2014 : Debugging entitlement issues in Maps, iCloud, In-App, Keychain, or GameCenter Tue, 29 Jan 2013 : Use VIM as an Xcode alternative Wed, 7 Dec 2011 : Fast NSDictionary traversal in Objective-C
{:keyword-tags (:ios :cocoa),
:projects ({:project "Sarbatka", :link "/electronic-music.html"}),
:postlist
({:title "Blogstrapped.",
:url "/2011/12/01/blogstrapped/",
:tags "entrepeneurship blog",
:keyword-tags (:entrepeneurship :blog),
:date "Thu, 1 Dec 2011",
:keywords "entrepeneurship videro fear unknown stylemac",
:keyword-keywords
(:entrepeneurship :videro :fear :unknown :stylemac)}
{:title "Fast NSDictionary traversal in Objective-C",
:url "/2011/12/07/fast-nsdictionary-traversal-in-objective-c/",
:tags "objective-c ios cocoa",
:keyword-tags (:objective-c :ios :cocoa),
:date "Wed, 7 Dec 2011"}
{:title "How the iPad can improve focus",
:url "/2011/12/09/how-the-ipad-can-improve-focus/",
:tags "opinion",
:keyword-tags (:opinion),
:date "Fri, 9 Dec 2011"}
{:title "Use VIM as an Xcode alternative",
:url "/2013/01/29/use-vim-as-xcode-alternative-ios-mac-cocoa/",
:tags "cocoa objective-c ios",
:keyword-tags (:cocoa :objective-c :ios),
:date "Tue, 29 Jan 2013"}
{:title "Now Running Clojure",
:url "/2014/01/20/now-running-clojure/",
:tags "clojure blog",
:keyword-tags (:clojure :blog),
:date "Mon, 20 Jan 2014"}
{:title
"Debugging entitlement issues in Maps, iCloud, In-App, Keychain, or GameCenter",
:url
"/2014/01/21/debugging-entitlement-maps-icloud-gamecenter-issues/",
:tags "ios cocoa",
:keyword-tags (:ios :cocoa),
:date "Tue, 21 Jan 2014",
:keywords "ios cocoa entitlements",
:keyword-keywords (:ios :cocoa :entitlements)}
{:title
"Clojure/Enlive Static Site Generator that keeps your HTML intact",
:url
"/2014/01/22/clojure-enlive-static-site-generator-that-keeps-html-intact/",
:tags "blog clojure",
:keyword-tags (:blog :clojure),
:date "Wed, 22 Jan 2014",
:keywords "clojure static site generator jekyll html enlive",
:keyword-keywords
(:clojure :static :site :generator :jekyll :html :enlive)}
{:title "Finding a good URL Partitioning Scheme for PostgreSQL",
:url "/2014/01/24/finding-url-partitioning-scheme-postgres/",
:tags "postgresql clojure",
:keyword-tags (:postgresql :clojure),
:date "Fri, 24 Jan 2014",
:keywords "clojure postgresql partitioning scheme",
:keyword-keywords (:clojure :postgresql :partitioning :scheme)}
{:title "An Emacs Lisp tooling tutorial, writing a bulk mailer",
:url "/2014/01/29/emacs-lisp-tooling-tutorial-writing-bulk-mailer/",
:tags "emacs",
:keyword-tags (:emacs),
:date "Wed, 29 Jan 2014",
:keywords
"emacs lisp bulk mailer tutorial email vim vimscript evil",
:keyword-keywords
(:emacs :lisp :bulk :mailer :tutorial :email :vim :vimscript :evil)}
{:title
"Creating a Swift syntax extension: the Lisp 'cond' function",
:url "/2014/06/08/writing-simple-syntax-extensions-in-swift/",
:tags "swift ios cocoa",
:keyword-tags (:swift :ios :cocoa),
:date "Sun, 8 Jun 2014",
:keywords
"clojure lisp swift cond syntax macro extension cocoa ios feature",
:keyword-keywords
(:clojure
:lisp
:swift
:cond
:syntax
:macro
:extension
:cocoa
:ios
:feature)}
{:title "Swift optionals made simple",
:url "/2014/06/13/swift-optionals-made-simple/",
:tags "swift ios cocoa",
:keyword-tags (:swift :ios :cocoa),
:date "Fri, 13 Jun 2014",
:keywords
"lisp swift optional scala simple optionals switch chaining feature",
:keyword-keywords
(:lisp
:swift
:optional
:scala
:simple
:optionals
:switch
:chaining
:feature)}
{:title "Generic method overloading by protocol in Swift",
:url "/2015/06/17/swift-method-overloading-by-protocol/",
:tags "swift ios cocoa",
:keyword-tags (:swift :ios :cocoa),
:date "Wed, 17 Jun 2015",
:keywords
"swift optional simple overloading method protocol extensions generics feature",
:keyword-keywords
(:swift
:optional
:simple
:overloading
:method
:protocol
:extensions
:generics
:feature)}
{:title "Using try / catch in Swift with asynchronous closures",
:url "/2015/06/19/swift-try-catch-asynchronous-closures/",
:tags "swift ios",
:keyword-tags (:swift :ios),
:date "Fri, 19 Jun 2015",
:keywords "swift try catch errortype closure async result feature",
:keyword-keywords
(:swift :try :catch :errortype :closure :async :result :feature)}
{:title "Debugging advanced compilation errors in ClojureScript",
:url "/2015/07/02/debugging-clojurescript-advanced-compilation/",
:tags "clojure",
:keyword-tags (:clojure),
:date "Thu, 2 Jul 2015",
:keywords "debugging clojure clojurescript externs",
:keyword-keywords (:debugging :clojure :clojurescript :externs)}
{:title "Tuples in Swift, Advanced Usage and Best Practices",
:url "/2015/07/19/tuples-swift-advanced-usage-best-practices/",
:tags "swift",
:keyword-tags (:swift),
:date "Sun, 19 Jul 2015",
:keywords "swift tuples generics feature",
:keyword-keywords (:swift :tuples :generics :feature)}
{:title "Match Me if you can: Swift Pattern Matching in Detail.",
:url "/2015/08/20/swift-pattern-matching-in-detail/",
:tags "swift ios cocoa",
:keyword-tags (:swift :ios :cocoa),
:date "Thu, 20 Aug 2015",
:keywords
"feature lisp swift optional scala simple optionals switch chaining for pattern matching clojure haskell",
:keyword-keywords
(:feature
:lisp
:swift
:optional
:scala
:simple
:optionals
:switch
:chaining
:for
:pattern
:matching
:clojure
:haskell)}
{:title "Optional throw via try? in Swift 2 beta 6",
:url "/2015/08/25/optional-throw-swift/",
:tags "swift",
:keyword-tags (:swift),
:date "Tue, 25 Aug 2015",
:keywords
"swift error throw result either rethrow try syntax swift2",
:keyword-keywords
(:swift
:error
:throw
:result
:either
:rethrow
:try
:syntax
:swift2)}
{:title "Getting your iPhone 6s Chip Foundry from Swift",
:url "/2015/09/30/getting-iphone6s-foundry-from-swift/",
:tags "swift",
:keyword-tags (:swift),
:date "Wed, 30 Sep 2015",
:keywords
"swift iphone6s iphone tsmc samsung gestalt private api foundation",
:keyword-keywords
(:swift
:iphone6s
:iphone
:tsmc
:samsung
:gestalt
:private
:api
:foundation)}
{:title "Advanced & Practical Enum usage in Swift",
:url "/2015/10/17/advanced-practical-enum-examples/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Sat, 17 Oct 2015",
:keywords
"feature swift enum algebraic caseclass union case switch pattern simple practical advanced example",
:keyword-keywords
(:feature
:swift
:enum
:algebraic
:caseclass
:union
:case
:switch
:pattern
:simple
:practical
:advanced
:example)}
{:title "The Swift Reflection API and what you can do with it",
:url "/2015/10/24/swift-reflection-api-what-you-can-do/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Sat, 24 Oct 2015",
:keywords
"feature swift reflection struct class displayType mirror api reflecting any anyobject",
:keyword-keywords
(:feature
:swift
:reflection
:struct
:class
:displayType
:mirror
:api
:reflecting
:any
:anyobject)}
{:title "Reduce all the things",
:url "/2015/11/30/reduce-all-the-things/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Mon, 30 Nov 2015",
:keywords
"feature swift reduce map filter group partition split interpose chunk functional programming flatMap",
:keyword-keywords
(:feature
:swift
:reduce
:map
:filter
:group
:partition
:split
:interpose
:chunk
:functional
:programming
:flatMap)}
{:title
"Swift Package Manager: Create and Use a X11 package on Linux",
:url "/2015/12/08/swift-ubuntu-x11-window-app/",
:tags "swift linux",
:keyword-tags (:swift :linux),
:date "Tue, 8 Dec 2015",
:keywords "linux x11 swift libx11 xserver xorg",
:keyword-keywords (:linux :x11 :swift :libx11 :xserver :xorg)}
{:title "Hirundo: Comfortably follow Swift Mailing Lists on OSX",
:url "/2016/02/02/hirundo-mac-app-swift-mailing-lists/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Tue, 2 Feb 2016",
:keywords
"swift mac cocoa mailing list swift-dev swift-eveolution swift-users reading macosx",
:keyword-keywords
(:swift
:mac
:cocoa
:mailing
:list
:swift-dev
:swift-eveolution
:swift-users
:reading
:macosx)}
{:title "Three tips for concise Swift using the Guard statement",
:url "/2016/03/29/three-tips-for-clean-swift-code/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Tue, 29 Mar 2016",
:keywords
"swift mac cocoa guard let enum pattern matching patterns",
:keyword-keywords
(:swift :mac :cocoa :guard :let :enum :pattern :matching :patterns)}
{:title "Using Git Hooks to prevent commiting test code",
:url "/2016/04/04/prevent-accidental-test-code-commits/",
:tags "git",
:keyword-tags (:git),
:date "Mon, 4 Apr 2016",
:keywords "git hook commit debug test code",
:keyword-keywords (:git :hook :commit :debug :test :code)}
{:title
"Force optionals in multi-unwrapped \"guard let\" or \"if let\"",
:url
"/2016/04/14/force-optionals-in-guard-or-let-optional-binding/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Thu, 14 Apr 2016",
:keywords
"swift guard let unwrap bind binding unwrapped optional some none optionals",
:keyword-keywords
(:swift
:guard
:let
:unwrap
:bind
:binding
:unwrapped
:optional
:some
:none
:optionals)}
{:title "Raw value initializers for enums with associated types",
:url "/2016/04/23/associated-types-enum-raw-value-initializers/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Sat, 23 Apr 2016",
:keywords
"swift optional enum raw value initializers associated type",
:keyword-keywords
(:swift
:optional
:enum
:raw
:value
:initializers
:associated
:type)}
{:title "SwiftWatch",
:url "/2016/04/28/swiftwatch/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Thu, 28 Apr 2016",
:keywords
"swift hackernews reddit designernews lamernews socialnews swiftlang programming community post vote comment",
:keyword-keywords
(:swift
:hackernews
:reddit
:designernews
:lamernews
:socialnews
:swiftlang
:programming
:community
:post
:vote
:comment)}
{:title "Data in Swift 3 parsing a Doom WAD File",
:url "/2016/07/15/swift3-nsdata-data/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Fri, 15 Jul 2016",
:keywords "swift doom wad lumps data nsdata swift3 binary bytes",
:keyword-keywords
(:swift :doom :wad :lumps :data :nsdata :swift3 :binary :bytes)}
{:title "Value Types for Simple Difference Detection",
:url "/2017/09/30/value-types-for-simple-difference-detection/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Sat, 30 Sep 2017",
:keywords
"swift value types uitableview uicollectionview valuetypes struct class equatable tuple",
:keyword-keywords
(:swift
:value
:types
:uitableview
:uicollectionview
:valuetypes
:struct
:class
:equatable
:tuple)}
{:title "Taming SourceKitService for Less Xcode Memory Consumption",
:url "/2017/10/08/taming-sourcekitd/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Sun, 8 Oct 2017",
:keywords "xcode sourcekit swift SourceKitService",
:keyword-keywords (:xcode :sourcekit :swift :SourceKitService)}
{:title "Patterns for Working With Associated Types",
:url "/2017/12/10/patterns-for-working-with-associated-types/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Sun, 10 Dec 2017",
:keywords
"swift protocol protocols associated associatedtype typealias pattern pat",
:keyword-keywords
(:swift
:protocol
:protocols
:associated
:associatedtype
:typealias
:pattern
:pat)}
{:title "Useful Optional Extensions",
:url "/2018/01/10/optional-extensions/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Wed, 10 Jan 2018",
:keywords "swift protocol optional optionals extensions",
:keyword-keywords
(:swift :protocol :optional :optionals :extensions)}
{:title "Expanding Swift's Reach",
:url "/2018/05/03/expanding-swifts-reach/",
:tags "swift linux",
:keyword-tags (:swift :linux),
:date "Thu, 3 April 2018",
:keywords "swift linux server opensource",
:keyword-keywords (:swift :linux :server :opensource)}),
:tags
"benedikt, c, clojure, clojurescript, cocoa, entitlements, html, ios, javascript, mac, objective-c, photodesk, research, stylemac, terhechte",
:type :post,
:keywords "ios cocoa entitlements",
:title
"Debugging entitlement issues in Maps, iCloud, In-App, Keychain, or GameCenter",
:author "Benedikt Terhechte",
:categories
({:tag "blog", :url "/tags/blog/index.html", :count 3}
{:tag "clojure", :url "/tags/clojure/index.html", :count 4}
{:tag "cocoa", :url "/tags/cocoa/index.html", :count 20}
{:tag "emacs", :url "/tags/emacs/index.html", :count 1}
{:tag "entrepeneurship",
:url "/tags/entrepeneurship/index.html",
:count 1}
{:tag "git", :url "/tags/git/index.html", :count 1}
{:tag "ios", :url "/tags/ios/index.html", :count 21}
{:tag "linux", :url "/tags/linux/index.html", :count 2}
{:tag "objective-c", :url "/tags/objective-c/index.html", :count 2}
{:tag "opinion", :url "/tags/opinion/index.html", :count 1}
{:tag "postgresql", :url "/tags/postgresql/index.html", :count 1}
{:tag "swift", :url "/tags/swift/index.html", :count 23}),
:url
"/2014/01/21/debugging-entitlement-maps-icloud-gamecenter-issues/",
:options "toc:nil",
:blog-index nil,
:watching nil,
:site-title "Appventure",
:keyword-keywords (:ios :cocoa :entitlements)}
[{:keyword-tags (:ios :cocoa),
:tags "ios cocoa",
:date "Tue, 21 Jan 2014",
:footnotes nil,
:meta
{:title
"Debugging entitlement issues in Maps, iCloud, In-App, Keychain, or GameCenter",
:keyword-tags (:ios :cocoa),
:tags "ios cocoa",
:keyword-keywords (:ios :cocoa :entitlements),
:keywords "ios cocoa entitlements",
:options "toc:nil"},
:content
"<p>\nI recently ran into an issue where a Mac App did lack an entitlement even though I had all entitlements properly set up in my account. I also had performed rigourous testing prior to submission, which made it even more worrisome as I had no idea how to proceed.\n</p>\n\n<p>\nSince everything was running fine on my machine, and since the error in question was happening when users installed the app, I needed a way to figure out what happened to the binary right before Xcode submits it to the App Store. \n</p>\n\n<p>\nIf you happen to have such an issue, i.e. an Apple Maps or iCloud or Game Center or Keychain Sharing or In-App Purchase error that only happens on your customers system, there is indeed a way to debug this issue.\n</p>\n\n<p>\n<a href=\"https://developer.apple.com/library/mac/technotes/tn2265/_index.html\">In Technical Note TN2265, Troubleshooting Push Notifications</a>, Apple explains a very useful process that explains what to do in such situations as outlined above. In the '<b>Error Delegate Callback</b>' section, the document explains how you can export the App from the Organizer just as it would be submitted to the App Store, and how you can inspect the result in order to figure out whether all the correct entitlements are set:\n</p>\n\n<ol class=\"org-ol\">\n<li>Export the app as Mac Installer Package, using the same identity that you use when submitting to the Mac App Store\n</li>\n<li>Locate the generated Pkg file in the Terminal\n</li>\n<li>Run the following code in the Terminal\n</li>\n</ol>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-bash\">pkgutil --expand \"YourApp.pkg\" Expanded_pkg\nopen Expanded_pkg/com.yourcompany.yourapp/Payload\ncodesign -d --entitlements - \"Expanded_pkg/com.yourcompany.yourapp/YourApp.app\"\n</pre>\n</div>\n\n<p>\nThis will show you the list of entitlements that are included in your app upon submission to the App Store. This is a very useful thing to know, in fact so useful, that Apple writes, right below the process.\n</p>\n\n<blockquote>\n<p>\nNote: This is a useful test to perform on your distribution builds before submitting them to the App Store.\n</p>\n</blockquote>\n\n<p>\nAbsolutely, it would also be great if such a Gem wasn't hidden in a page that just deals with Push Notification issues.\n</p>\n",
:keywords "ios cocoa entitlements",
:title
"Debugging entitlement issues in Maps, iCloud, In-App, Keychain, or GameCenter",
:filename
"2014-01-21-debugging-entitlement-maps-icloud-gamecenter-issues.org",
:id -1123572331,
:url
"/2014/01/21/debugging-entitlement-maps-icloud-gamecenter-issues/",
:javadate #inst "2014-01-20T23:00:00.000-00:00",
:keyword-keywords (:ios :cocoa :entitlements)}]