$(AppIdentifierPrefix) in .entitlements file is not getting replaced with the actual AppIdentifierPrefix. Can someone please shine some light onto this issue?
So here is my understanding of the YourApp.entitlements file that gets added to your project when you add capabilities like iCloud or Game Centre to your application.
(I'd love to see some pointers to official documentation ... if any exists.)
What are these entitlements files used for?
So first of all, the .entitlements is only in your project for the build process. It should not end up in the final .app product. If it does, select the .entitlements file and in the File Inspector, clear it's Target Membership. (This is how Xcode generated these files actually, without any target membership)
So what is the .entitlements file used for then? It is part of the build process where it is taken and processed and put in your final application bundle in two forms:
First: the contents of the .entitlements file is embedded in the embedded.mobileprovision file. This is a signed property list with a binary signature on top but if you open it up in a text editor you can see there is a <key>Entitlements</key> section that should have the processed entitlements in there.
Second: there is also a copy of the .entitlements file called archived-expanded-entitlements.xcent. This is essentially the same file as the original .entitlements file except that it has been processed.
What preprocessor values can be used in the .entitlements file
I don't think the processing of the .entitlements file is documented anywhere. There most certainly is a pre-processor running over it, so that things like $(AppIdentifierPrefix) are replaced with the actual value. However, this seems to be not the same as the one that is used for the Info.plist file.
The $(AppIdentifierPrefix) is the same as the Team Identifier that you may have configured in your Xcode project. You can find the configured Team under your target's General settings in the Identity section. If team is set to None then there is a good change that $(AppIdentifierPrefix) won't be set.
So to finally answer your question: if you look at those two files that I mentioned above, and you still see the $(AppIdentifierPrefix) is not correctly substituted, make sure your project has a Team Identifier configured.
How does Xcode know what entitlements file to use for your target?
In your build settings you can look at the Code Signing Entitlements settings to find out what file Xcode uses for each build configuration. Usually Debug and Release use the same entitlements file but you can change that.
(For example, for Firefox for iOS we have build configurations for Nightly, Aurora, Beta and Release builds. These all have different entitlements files. The reason we have different entitlements files is because we could not make the .entitlements pre-processor recognize settings like $(PRODUCT_NAME:rfc1034identifier) - i'd love to hear if there is a way to do that because that will make our build simpler.)
What tool processes the .entitlements files?
Not entirely sure. But if you look in the build logs, you will see some reference to a builtin-productPackagingUtility tool. This seems to be an internal Xcode command, not something actually present as a command line tool. So that is not very useful.
Now you know pretty much everything that I know about .entitlements files :-)
(I'd love comments and turn this answer into the definitive guide to entitlements files - i think there is a lot of confusion around them)
Related
I have been using Info.plist in my projects, but recently I noticed that freshly generated new projects don't contain them anymore, and Info.plist is instead generated by Xcode at build time, from Info.plist Values section in target's Build settings.
I like this, as it would allow me to ship two projects (beta and non-beta one) from a same folder, without special build steps modifying the Info.plist for each project.
However, I noticed that:
Many Info.plist keys are missing in Build settings (eg. ITSAppUsesNonExemptEncryption, or NSLocationAlwaysUsageDescription/NSLocationUsageDescription/NSLocationWhenInUseUsageDescription), so I cannot set them from there. There also doesn't appear to be any + sign when hovering, which would let me add another key into that section.
And the way of adding INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO; into a .pbxproj file, which I have found documented somewhere, no longer works.
Is there a way of adding additional keys into generated Info.plist? Or, is there a way of having both both Info.plist file in a filesystem, and Info.plist Values section in build settings, and make Xcode merge them during build?
Here is how the section looks like:
So, this was helpful (thank you Andrew!), but the core insight I got from experimenting is:
Xcode doesn't want to let you enter invalid keys in places they don't belong.
Build Settings only have basic properties, anything else belongs into the 'Info' section. Editing it will create a new Info.plist file with only the changed properties, which will then be merged with info.plist keys from build settings (I couldn't find a documentation for build order).
Some settings, like ITSAppUsesNonExemptEncryption for standalone watch-only apps have no place to go.
Apple mostly abandoned standalone watchapps, there is a ton of bugs around them and they don't care.
After cloning my Github repo, everything runs fine except the build fails because of this error "Reading data: The file "Info.plist" couldn't be opened because there is no such file."
I have tried every possible solution I could find, including deleting the file and creating a new one, deleting it from the Copy Bundle Resources, adding it to the Build Settings, etc. I have followed these posts among others on all of the solutions but nothing has worked. Error: The file “Info.plist” couldn’t be opened because there is no such file, Info.plist Utility Error: "Info.plist couldn't be opened because there is no such file"
I would really appreciate someone's help in finding a solution to this problem, and if you need any more information, please let me know.
Edit: Also for some reason when I looked in the project it's not the newest version that I had committed to Github. I was wondering how I can clone an exact commit? I was trying to look at this post but I'm not exactly sure where to find the remote address?
It's going to be pretty difficult to debug this without having a look at your project, if all fails you might consider making a copy, remove all source files and share that shallow copy on a public repo.
Otherwise, on top of what #Asperi had already said, be sure to:
Clean build folder before each try you make to fix this (Command+Option+Shift+K), just in case
Open the build logs (see below) and using the search (Command+F) look of an entry that starts with ProcessInfoPlistFile. Check if there's something wired with the path there, check if the file pointed by that path is missing, if it has the right project name etc
If you're building multiple targets, be sure to check if each has a valid .plist, not just the main one.
Open yourprojectname.xcodeproj/project.pbxproj in a plain text editor (e.g. write open yourprojectname.xcodeproj/project.pbxproj in terminal) and search for Info.plist, be sure that each entry has a valid path (the path specified there actually exists)
Update: Although it is not important how the info plist file is named physically in your project, because Xcode renames it always into Info.plist during product bundle creation phase, but to avoid confusing among community, let's assume that your info plist is named Info.plist.
Check the followings:
1) Is Info.plist present in file system after clone?
2) Is correct related path is set for Info.plist in project Build Settings (INFOPLIST_FILE tag)?
3) Is Info.plist file not damaged - opened by Xcode as a document (Info tab in project settings should show it as well)?
Note: Info.plist should not be added in target's Resources, it is copied by Xcode from mentioned above INFOPLIST_FILE (and renamed if needed into Info.plist!)
The following applies to the question, comments and answers here:
Info.plist should be capitalized — if not it could easily explain your problem.
NOTE: Several comments and answers are using lowercase info.plist,
this just adds fuel to the fire. It's best to be specific (especially when
it comes to this), because that minor detail can make a huge
difference.
The answer awarded the bounty is absolutely false information. The following excerpt comes directly from the documentation previously linked:
Important: In the sections that follow, pay attention to the capitalization of files and directories that reside inside a bundle. The NSBundle class and Core Foundation bundle functions consider case when searching for resources inside a bundle directory. Case mismatches could prevent you from finding your resources at runtime.
Source: https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/AboutInformationPropertyListFiles.html#//apple_ref/doc/uid/TP40009254-SW1
Strange issue:
I have a project with tens of targets and a single Info.plist file because it uses variables for it's data. This makes it easier to maintain if I need new ones added.
I need to translate this app by using XLIFF files. The problem is that the export dialog gives a "Duplicate info.plist export for localization" error and stops. This happens because all targets use the same Info.plist
If I remove the entry from all targets and leave it to just one, it works fine but it's a lot of work to do each time.
Now, a good solution would be to add the plist file to the project's entry which it seems would make it work for all targets, but it doesn't. Xcode complaints on build that the Info.plist file has not been found.
Any suggestions?
I'm sure there is something messed up in the project file but I have not been able to find it (it's a legacy project new to me).
If I remove the reference to info.plist in the project, then it will successfully import and export, which is a workaround, but not ideal (obviously, although it's easy to revert).
I have searched for duplicate info.plist files and there are none that I can see (there actually are for the watchkit extension and app, but those are named differently anyway).
The actual name of my info.plist is like myapp-info.plist, but it is correctly named in the build settings--the project builds fine.
I have googled the heck out of this and can't find any other reports so I'm really stuck. Next step is to burn an Apple tech support request and when I do, I'll report back, but I thought I would ask the SO community first.
Thank you!
I had this same error. To fix it, I had to localize the *-info.plist file. Select the info.plist file and click "Localize..." in the File Inspector pane.
I don't know if you have solved this problem but I had the same issue. I think it happens when you change the project name and the build settings do not do its job to reflect the change. The Test info.plist refers to the same target original plist and seems to cause this problem.
Go to build settings in your project>Target>Project-name-Tests>Build Settings. Then locate Packaging>Info.plist File and change the folder to project-nameTest/Info.plist.
I hope this does the trick.
My experience was different here. I have multiple targets that all use the same code base. At some point (ostensibly due to a bad manual merge) the Info.plist setting in the Build Settings tab got set to the same value for multiple targets.
Once I straightened all of those out, I was able to export the Xliff file without any issues.
I was receiving this error message in Xcode 7.3.1 and what I did was create a new empty project in Xcode and model my info.plist files after that. This involved:
renaming my [app name]-Info.plist file to Info.plist and moving it out of Supporting Files to the main folder
going to project target (General tab) and selecting the renamed file. There should be a button for 'Choose Info.plist File'
doing similarly in the Tests folder. I don't think this step is necessary to fix the error but did it for consistency.
I was looking at this question on SO - Duplicate localized resource "/Localizable.strings" found xcode 6.1 - and I was able to export to .xliff successfully when I removed reference to the ProjectName-Info.plist file.
I re-added the file, and the project compiled successfully. You have to remove the reference again every time you want to export/import and re-add the file again.
I wasn't able to import updated .xliff files successfully, but I'm thinking on using just Localizable.strings file moving forward. I'm just happy that Project -> Editor -> Export for localization finally worked!
I have a unique issue, where Xcode picks up the wrong info.plist file when compiling. I have two targets, one is in the release version and the other is in the beta configuration(scheme). We have different files in the app bundle, which are used based on the target and also the build configuration.
When I am running the beta configuration, it runs fine, but when I try to run the release version of the application, xcode still picks up the beta build configurations.
I have tried various ways to change the plist file, deleted the files,added them again, edited the build phases, edited the build settings in the copy bundle resources. Closed xcode and also the simulators. I donot know what I am missing in these.
I have also made sure only one info.plist file is associated with one target. The targets shows the correct info while checking, can you please help me with this. The problem occurred during merging of two code versions.
Update:
I went ahead and deleted the info.plist file, which shows up in both the targets, but all I receive is an error while compiling info.plist utility error. It is pointing the plist file, which I deleted. The info, build settings, show the correct plist files
Update 2
I went ahead and also changed the files, changed build settings, packaging files, but still the target picks up the other file. Any way to fix this?
It happened to me today and at nothing written here helped
the settings ARE ok but resetting it didn't help
the cache cleaning didn't help
BUT what helped is:
recreating the scheme with 100% the same settings :) it works fine now
You don't have to clear any cache, just edit the scheme of the new target and change the run executable in the info tab to the new executable target.
I have fixed this problem by using the plist file irrespective of the configuration. So, irrespective of the target if a corresponding scheme had beta configuration I will use one plist file, if the other target is the release version so I will use another plist file.