8

I am implementing universal deep linking in my app. When I registered my different domains, it creates an AppName.entitlements file

I would like to read the values of this file like a plist.

I tried

if let path = NSBundle.mainBundle().pathForResource("AppName", ofType:
"entitlements") { }

but it returns nil

Is it possible to read such files?

mfaani
  • 33,269
  • 19
  • 164
  • 293
kschaeffler
  • 4,083
  • 7
  • 33
  • 41
  • `nil` means the file couldn't be located. Check the "Discussion" section in [the docs for this method](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSBundle_Class/#//apple_ref/occ/instm/NSBundle/pathForResource:ofType:) so you can see the approach it uses to find the file. Make sure the file is locatable by that algorithm (and that you spelled everything correctly). Especially note: *"It does not recurse through other subfolders at any of these locations"* – Aaron Brager May 17 '16 at 15:39

4 Answers4

6

That file isn't copied in to your app (see Xcode's target checkbox). It is only used for building

the entitlements are a config file for Xcode

so: no

Note that even if you add it manually to your bundle, it produces a warning similar to: Warning: The Copy Bundle Resources build phase contains this target's Info.plist file

Workaround said warning like: https://stackoverflow.com/a/56044915/8740349

Top-Master
  • 7,611
  • 5
  • 39
  • 71
Daij-Djan
  • 49,552
  • 17
  • 113
  • 135
3

The solution I found:

add the appGroup into Info.Plist file

<key>appGroup</key>
<string>group.com.acronis.mobile.ios.development</string>

To read the string use the code below:

extension String {

    // MARK: - Static

    static var appGroup: String = {
        guard let bundleAppGroup = Bundle.main.infoDictionary?["appGroup"] as? String else {
            fatalError("The application must contain appGroup in Info.plist file")
        }
        return bundleAppGroup
    }()
}

Change the entitlements and Info.plist at before build time using your custom script if needed.

Vyacheslav
  • 26,359
  • 19
  • 112
  • 194
3

I dove into this subject a bit and it is actually quite simple.

You use a run script to grab the entitlements and merge it into Info.plist:

ENTITLEMENTS= # Path to Project.entitlements #
INFOPLIST= # Path to Info.plist #
echo "Writing entitlements to Info.plist"; 
KEY="entitlements-from-script"; 
/usr/libexec/PlistBuddy -c "delete $KEY" "$INFOPLIST"; 
/usr/libexec/PlistBuddy -c "add $KEY dict" "$INFOPLIST"; 
/usr/libexec/PlistBuddy -c "merge $ENTITLEMENTS $KEY" "$INFOPLIST";

Now you can use it in code:

let entitlements = Bundle.main.infoDictionary?["entitlements-from-script"]
Casper Zandbergen
  • 3,419
  • 2
  • 25
  • 49
0

While looking into this I found the following blog post https://medium.com/swlh/reading-application-entitlements-with-swift-65cff184e840 where @mateuszmatrejek explains how to parse the binary file at run time to extract the entitlements.

This approach is very low level and complex. The key advantage I see with this approach is if you are working on a framework or library this would work to read the entitlements of the app which is using importing your lib or framework.

TMin
  • 2,280
  • 1
  • 25
  • 34