Get an Entry from a Property List in your App Bundle
We save most of the configuration information for our providers in Property Lists. Apps generated
with SwiftyLaunch use them as sort of segregated .env
files. Every module with a provider has its
a property list located in the Config
folder.
To access it and to avoid boilerplate, we have created the global getPlistEntry
function.
It simply takes in the name of the entry (key) in the property list, and the name of the property list and returns the value as string.
Function definition:
public func getPlistEntry(
_ plistEntry: String,
in plistName: String
) throws -> String { }
In case of an error, it throws an error of type PlistReadError
.
Error definition:
public enum PlistReadError: String, LocalizedError {
case noPlist = "PlistReadError: No .plist file found"
case noEntry = "PlistReadError: No entry found in Property List"
public var errorDescription: String? { self.rawValue }
}
Usage Example
From initialization of RevenueCat in InAppPurchaseKit
:
import AnalyticsKit
import RevenueCat
import SharedKit
public class InAppPurchases: ObservableObject {
@discardableResult
// Initialize RevenueCat with the API key from the property list
// Returns true if everything went well, false otherwise
// Is called from the main app's AppDelegate
public static func initRevenueCat() -> Bool {
do {
// get the API key ("REVENUECAT_API_KEY") from the property list ("RevenueCat-Info")
let apiKey = try getPlistEntry("REVENUECAT_API_KEY", in: "RevenueCat-Info")
// Initialize RevenueCat with the api key
Purchases.configure(withAPIKey: apiKey)
// return true if everything went well
return true
} catch {
// caputre an error if something went wrong and return false
Analytics.capture(
.error,
id: "rc_setup",
longDescription: "[IAP] RevenueCat Init Error: \(error)",
source: .iap
)
return false
}
}
}
Note: this function works on property lists that are members of the Main App Target.
Even though the property files themselves are located within different module folders, they are members of the main app target. Their placement within the modules is simply there for better organization.