Sources/UberCore/ConfigurationProvider.swift (57 lines of code) (raw):

// // ConfigurationProvider.swift // UberCore // // Copyright © 2024 Uber Technologies, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import Foundation import UIKit import UberCore /// @mockable public protocol ConfigurationProviding { var clientID: String { get } var redirectURI: String { get } var sdkVersion: String { get } var serverToken: String? { get } static var isSandbox: Bool { get } func isInstalled(app: UberApp, defaultIfUnregistered: Bool) -> Bool } public struct ConfigurationProvider: ConfigurationProviding { // MARK: Public Properties public static var plistName: String = "Info" // MARK: Private Properties private let parser: PlistParser // MARK: Initializers public init() { let parser = PlistParser(plistName: Self.plistName) self.parser = parser guard let contents: [String: Any] = parser[ConfigurationKey.base] else { preconditionFailure("Configuration item not found: \(ConfigurationKey.base)") } guard let clientID = contents[ConfigurationKey.clientID] as? String else { preconditionFailure("Configuration item not found: \(ConfigurationKey.base)/\(ConfigurationKey.clientID)") } guard let redirectURI = contents[ConfigurationKey.redirectURI] as? String else { preconditionFailure("Configuration item not found: \(ConfigurationKey.base)/\(ConfigurationKey.clientID)") } self.clientID = clientID self.redirectURI = redirectURI Self.isSandbox = (contents[ConfigurationKey.sandbox] as? Bool) ?? false self.serverToken = contents[ConfigurationKey.serverToken] as? String } // MARK: ConfigurationProviding public let clientID: String public let redirectURI: String public let serverToken: String? public static var isSandbox: Bool = false /// Attempts to determine if the provided `UberApp` is installed on the current device. /// First checks the Info.plist to see if the required url schemes are registered. If not registered, /// returns `defaultIfUnregistered`. /// If registered, returns whether the scheme can be opened, indicating if the app is installed. /// /// - Parameters: /// - app: The Uber application to check /// - defaultIfUnregistered: The boolean value to return if the app's url scheme is not registered in the Info.plist /// - Returns: A boolean indicating if the app is installed public func isInstalled(app: UberApp, defaultIfUnregistered: Bool) -> Bool { guard let registeredSchemes: [String] = parser["LSApplicationQueriesSchemes"], registeredSchemes.contains(where: { $0 == app.deeplinkScheme }), let url = URL(string: "\(app.deeplinkScheme)://") else { return defaultIfUnregistered } return UIApplication.shared.canOpenURL(url) } /// The current version of the SDK as a string public var sdkVersion: String { guard let version = Bundle(for: UberButton.self).object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String else { return "Unknown" } return version } // MARK: Constants private enum ConfigurationKey { static let base = "Uber" static let clientID = "ClientID" static let redirectURI = "RedirectURI" static let serverToken = "ServerToken" static let sandbox = "Sandbox" } }