Using info.plist for storing target-specific values for a multi-target app - iphone

I have a multi-target iPhone app which currently includes a header file with constant definitions that are conditionally included at build time depending on which target is being built.
However, I was wondering if it might be better to instead include this information in the info.plist for the build, as this generally holds target-specific meta, so logically seems more appropriate.
Therefore, my questions are:
Is it acceptable to include custom (non-Apple defined) keys in the info.plist file?
Is this a suitable place to include meta for the app which differ between targets?

It is acceptable and suitable.
The Info.plist file is preprocessed (must be enabled in project settings by setting Packaging / Preprocess Info.plist File to Yes) by the C pre-processor, so you can have variables (in the form of ${VARIABLE_NAME}). These variables can be defined in the User Defined section in Xcode's target info, making it very easy to switch their value from one target to another.

Related

Unable to select pre-registered files types using UIDocumentPickerViewController with with pre-iOS 14 target

I'm using a document picker to import data into an app. One of the files to import is a .GPX (it's actually an XML file of GPS data, but that's not relevant). I define a custom file type (as it's not covered by the standard file types covered within UniformTypeIdentifiers)
let documentsPicker = UIDocumentPickerViewController(documentTypes: ["com.sourceapp.gpx"], in: .open)
and register it in info.plist as a Document type, and include this in Exported type identifiers and, seeing as it is not a bespoke file type, in Imported type identifiers. These are all still required as the app target is pre-iOS 14 (for 14+ it's not necessary to add the items to info.plist).
This works fine in the simulator where it's a clean environment without any other apps installed. On a device however it doesn't work, and the file is greyed out and not selectable. I'm reasonably certain this is because a custom file type with the same extension is already registered by another app.
So how do I go about using a file type that has already been registered? There must be a "correct" way to go about this as it must be a common scenario.
My understanding was that this is what the Imported type identifiers was for, but I can't seem to get this to work. This may be because I'm not defining the imported type in exactly the same way as the first app to register it.
If so, how do I see what has already been registered, and reuse it? This would need to be a generic apprach as a scenario where a different app has already regsitered the file type but in a different way is highly likely for a common file type such as .gpx
As background, when using a pre-defined file type such as "public.comma-separated-values-text" for a CSV file all works fine.
UPDATE:
I've since seen as the bottom line of documentation that the exported type identifiers overrides imported type identifiers, so have tried deleting the exported one, butit makes no difference.

Use custom file names for iOS launch images

Is it possible to define my own naming convention for iOS app splash/launch images as I can with Icon files (e.g. via an Info.plist entry), or must I stick to the ...#2x.png and ...-568h#2x.png naming?
You can change the root name (the “Default” bit) with the UILaunchImageFile key, which has been available since iOS 3.2, but in that case the suffixes—#2x, -568h#2x, etc.—are still fixed. To supply a set of arbitrary images, you can use the UILaunchImages array, but be advised that that API is iOS 7-only.
If you use an Asset Catalog (new in XCode5), you can use whatever file naming convention you like. The Asset Catalog takes care of mapping a logical name for an image resource to a set of files on disk.

How to Localize NSPhotoLibraryUsageDescription key (ALAssets)

I'm trying to localize the NSPhotoLibraryUsageDescription key defined in the application's info.plist file (reference here).
This key gives you a point to provide custom message when the app is first asking for access to your camera roll.
I'm using ALAssetsLibrary to enumerate assets groups (which triggers the access request message to pop-up).
So far my googling doesn't answer how I could achieve this.
I want to avoid localizing the whole info.plist file as it contain a lot more non-locale dependent content.
Anyone already solved this or have hints how to proceed?
There is a file you can create (which may be created for you when you create a project) called InfoPlist.strings. This file is used and localized much like the file Localizable.strings.
In it you would have and entry something like:
NSPhotoLibraryUsageDescription = "Test of new Photos warnings";
Note that there are no quotation marks around the key
I think as long as the key is included in info.plist, it will localized using the value in InfoPlist.string if it is available for the language. Otherwise it will use whatever is defined in info.plist.
I have my note here https://github.com/onmyway133/notes/issues/290, or you will get
Missing Info.plist key - This app attempts to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryUsageDescription key with a string value explaining to the user how the app uses this data.
Once these issues have been corrected, you can then redeliver the corrected binary.
Make sure
You declare the keys in Info.plist
You localize it in InfoPlist.strings
You don't need double quotes, like "NSPhotoLibraryUsageDescription" = "Test of new Photos warnings";, you can just use NSPhotoLibraryUsageDescription = "Test of new Photos warnings";
The only way to make this work for me was in Xcode to:
1) Go to Project target -> Info-> Localization-> Add localization
Added language there. This operation created the <projectName>/<LanguageInitials>.lproj folder.
2) I created file InfoPlist.strings inside the folder <projectName>/<LanguageInitials>.lproj;
3) I added the text:
NSPhotoLibraryUsageDescription = "<Add your translated text here>";
inside that InfoPlist.strings file.
4) I then added that folder to the project with File -> add new files to the project or drag and drop.
Note: to test this I:
Cleaned cache, set the language on simulator to be the new one, edited the language in scheme to be the new one at running on simulator and restarted the simulator.

Xcode - Importing different header file with same name based on Target

I have a project with multiple targets each of which builds a pretty similar versions of the app but with different images assets and plists. For plists/images that's fine but I use the ShareKit and Appirater frameworks which have header files with #defines for their config. For each version I believe need to import a different version of this header file, as the config is different for each app built by each target.
So target A has SHConfig.h
and target B has a DIFFERENT SHConfig.h
I could edit the source for these frameworks to import different headers based on the target but that'd be messy when I come to upgrade the frameworks.
Is there a better way to import different header files (with the same name) based on the target?
Assuming they're in different directories, set the Header Search Paths in each target to put the correct directory first.
You may want to set it to something like $(SRCROOT)/foo:$(HEADER_SEARCH_PATHS), though I'm not sure whether that's necessary.
What I found useful was to put the Common directory name in the header search path, and then to use a different #import. My directory structure was Common/Views/v1 and Common/Views/v2. I wanted the v1 for one target and the v2 for another.
In my case, the search path I used in Header Search Paths was:
$(SRCROOT)/../Common/
Then, I used:
#import <Views/v2/ActivityIndicator.h>
In the target that needed the second version (this finds $(SRCROOT)/../Common/Views/v2/ActivityIndicator.h).
Oddly, the other target (the first one I created) is fine without specifying the full path. I.e.,
#import "ActivityIndicator.h"
works to find $(SRCROOT)/../Common/Views/v1/ActivityIndicator.h
Following process solved the issue for me
Select specific target
Under "Build Phases" --> add "New Headers Phase" --> Expand "Headers" --> click on add(plus symbol) and --> browse to the file to be added specific for the target. (It will add file under 'project' section).
Repeat the process for other targets.
Tested on Xcode 10.2

Bundle Display Name in iPhone

Is it possible to modify the BundleDisplay name at runtime ???
Thanks
I'd be really surprised if you could, since doing so would require you to edit the Info.plist file, which is in a write-protected directory. Even if you could modify it, it would cause the code signature to no longer match the application bundle, and the app would refuse to launch.
The closest you can get to using a different display name is to provide localized versions of it.
If you set the Bundle Display Name to a variable ie ${MY_BUNDLE_DISPLAY_NAME} and make sure that gets set in your build phases or from your ENV, or from an XCCONFIG file when building from the command line, the name should be replaced with what you set it with.