Skip to content

Commit

Permalink
Update interface (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
noahsmartin authored Oct 31, 2024
1 parent ae0c3de commit dea1291
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 27 deletions.
2 changes: 1 addition & 1 deletion Example/DemoApp/UpdateUtil.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import ETDistribution

struct UpdateUtil {
static func checkForUpdates() {
ETDistribution.shared.checkForUpdate(apiKey: Constants.apiKey) { result in
ETDistribution.shared.checkForUpdate(params: CheckForUpdateParams(apiKey: Constants.apiKey)) { result in
switch result {
case .success(let releaseInfo):
if let releaseInfo {
Expand Down
4 changes: 2 additions & 2 deletions Example/DemoApp/UpdateUtilObjc.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@

@implementation UpdateUtilObjc
- (void) checkForUpdates {
[[ETDistribution sharedInstance] checkForUpdateWithApiKey:[Constants apiKey]
tagName:[Constants tagName]
CheckForUpdateParams *params = [[CheckForUpdateParams alloc] initWithApiKey:[Constants apiKey] tagName:[Constants tagName] requiresLogin:NO];
[[ETDistribution sharedInstance] checkForUpdateWithParams:params
onReleaseAvailable:^(DistributionReleaseInfo *releaseInfo) {
NSLog(@"Release info: %@", releaseInfo);
}
Expand Down
39 changes: 15 additions & 24 deletions Sources/ETDistribution.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,17 @@ public final class ETDistribution: NSObject {
@objc(sharedInstance)
public static let shared = ETDistribution()

/// Checks if there is an update available for the app, based on the provided `apiKey` and optional `tagName`.
/// Checks if there is an update available for the app, based on the provided `params`.
///
/// The `apiKey` is required to authenticate the request, and the `tagName` can optionally be
/// provided to differentiate if the same binary has been uploaded with multiple tags.
/// `tagName` is generally not needed, the SDK will identify the tag automatically.
///
/// - Parameters:
/// - apiKey: A `String` API key used for authentication.
/// - tagName: An optional `String` that is the tag name used when this app was uploaded.
/// - params: A `CheckForUpdateParams` object.
/// - completion: An optional closure that is called with the result of the update check. If `DistributionReleaseInfo` is nil, there is no updated available. If the closure is not provided, the SDK will present an alert to the user prompting to install the release.
///
/// - Example:
/// ```
/// checkForUpdate(apiKey: "your_api_key", tagName: nil) { result in
/// let params = CheckForUpdateParams(apiKey: "your_api_key")
/// checkForUpdate(params: params) { result in
/// switch result {
/// case .success(let releaseInfo):
/// if let releaseInfo {
Expand All @@ -40,41 +37,36 @@ public final class ETDistribution: NSObject {
/// }
/// }
/// ```
public func checkForUpdate(apiKey: String,
tagName: String? = nil,
public func checkForUpdate(params: CheckForUpdateParams,
completion: ((Result<DistributionReleaseInfo?, Error>) -> Void)? = nil) {
checkRequest(apiKey: apiKey, tagName: tagName, completion: completion)
checkRequest(params: params, completion: completion)
}

/// Checks if there is an update available for the app, based on the provided `apiKey` and `tagName`with Objective-C compatibility.
/// Checks if there is an update available for the app, based on the provided `params` with Objective-C compatibility.
///
/// The `apiKey` is required to authenticate the request, and the `tagName` can optionally be
/// provided to differentiate if the same binary has been uploaded with multiple tags.
/// `tagName` is generally not needed, the SDK will identify the tag automatically.
/// This function is designed for compatibility with Objective-C.
///
/// - Parameters:
/// - apiKey: A `String` API key used for authentication.
/// - tagName: An optional `String` that is the tag name used when this app was uploaded.
/// - params: A `CheckForUpdateParams` object.
/// - completion: An optional closure that is called with the result of the update check. If `DistributionReleaseInfo` is nil,
/// there is no updated available. If the closure is not provided, the SDK will present an alert to the user prompting to install the release.
/// - onError: An optional closure that is called with an `Error` object if the update check fails. If no error occurs, this closure is not called.
///
///
/// - Example:
/// ```
/// checkForUpdate(apiKey: "your_api_key", tagName: nil, onReleaseAvailable: { releaseInfo in
/// let params = CheckForUpdateParams(apiKey: "your_api_key")
/// checkForUpdate(params: params, onReleaseAvailable: { releaseInfo in
/// print("Release info: \(releaseInfo)")
/// }, onError: { error in
/// print("Error checking for update: \(error)")
/// })
/// ```
@objc
public func checkForUpdate(apiKey: String,
tagName: String?,
public func checkForUpdate(params: CheckForUpdateParams,
onReleaseAvailable: ((DistributionReleaseInfo?) -> Void)? = nil,
onError: ((Error) -> Void)? = nil) {
checkRequest(apiKey: apiKey, tagName: tagName) { result in
checkRequest(params: params) { result in
switch result {
case.success(let releaseInfo):
onReleaseAvailable?(releaseInfo)
Expand Down Expand Up @@ -103,8 +95,7 @@ public final class ETDistribution: NSObject {
super.init()
}

private func checkRequest(apiKey: String,
tagName: String?,
private func checkRequest(params: CheckForUpdateParams,
completion: ((Result<DistributionReleaseInfo?, Error>) -> Void)? = nil) {
#if targetEnvironment(simulator)
// Not checking for updates on the simulator
Expand All @@ -120,12 +111,12 @@ public final class ETDistribution: NSObject {
}

components.queryItems = [
URLQueryItem(name: "apiKey", value: apiKey),
URLQueryItem(name: "apiKey", value: params.apiKey),
URLQueryItem(name: "binaryIdentifier", value: uuid),
URLQueryItem(name: "appId", value: Bundle.main.bundleIdentifier),
URLQueryItem(name: "platform", value: "ios")
]
if let tagName = tagName {
if let tagName = params.tagName {
components.queryItems?.append(URLQueryItem(name: "tag", value: tagName))
}

Expand Down
70 changes: 70 additions & 0 deletions Sources/Models/CheckForUpdateParams.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//
// CheckForUpdateParams.swift
// ETDistribution
//
// Created by Noah Martin on 10/31/24.
//

import Foundation

/// A model for configuring parameters needed to check for app updates.
///
/// Note: `tagName` is generally not needed, the SDK will identify the tag automatically.
@objc
public final class CheckForUpdateParams: NSObject {

/// Create a new CheckForUpdateParams object.
///
/// - Parameters:
/// - apiKey: A `String` API key used for authentication.
/// - tagName: An optional `String` that is the tag name used when this app was uploaded.
/// - requiresLogin: A `Bool` indicating if user login is required before checking for updates. Defaults to `false`.
@objc
public init(apiKey: String,
tagName: String? = nil,
requiresLogin: Bool = false) {
self.apiKey = apiKey
self.tagName = tagName
self.loginSetting = requiresLogin ? .default : nil
}

/// Create a new CheckForUpdateParams object with a connection name.
///
/// - Parameters:
/// - apiKey: A `String` API key used for authentication.
/// - tagName: An optional `String` that is the tag name used when this app was uploaded.
/// - connection: A `String` connection name for a company. Will automatically redirect login to the company’s SSO page.
@objc
public init(apiKey: String,
tagName: String? = nil,
connection: String) {
self.apiKey = apiKey
self.tagName = tagName
self.loginSetting = .connection(connection)
}

/// Create a new CheckForUpdateParams object with a login setting.
///
/// - Parameters:
/// - apiKey: A `String` API key used for authentication.
/// - tagName: An optional `String` that is the tag name used when this app was uploaded.
/// - loginSetting: A `LoginSetting` to require authenticated access to updates.
public init(apiKey: String,
tagName: String? = nil,
loginSetting: LoginSetting) {
self.apiKey = apiKey
self.tagName = tagName
self.loginSetting = loginSetting
}

/// Type of authenticated access to required. The default case shows the Emerge Tools login page.
/// A custom connection can be used to automatically redirect to an SSO page.
public enum LoginSetting {
case `default`
case connection(String)
}

let apiKey: String
let tagName: String?
let loginSetting: LoginSetting?
}

0 comments on commit dea1291

Please sign in to comment.