Skip to content

Commit

Permalink
Release 1.6.1
Browse files Browse the repository at this point in the history
  • Loading branch information
rwbutler committed Sep 26, 2022
1 parent ce6690d commit 8890afb
Show file tree
Hide file tree
Showing 21 changed files with 139 additions and 112 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.6.1] - 2022-09-26
### Changed
- Added a public `init` for `UpdatesResult` to make unit testing easier in consumer projects.

## [1.6.0] - 2021-10-10
### Added
- Added another `promptToUpdate` function which does not require an `UpdatesResult` object which means that the function can be used without having to pass an `UpdatesResult` object around the calling app.
Expand Down
4 changes: 2 additions & 2 deletions Example/Updates.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = Updates/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 1.6.0;
MARKETING_VERSION = 1.6.1;
MODULE_NAME = ExampleApp;
PRODUCT_BUNDLE_IDENTIFIER = com.rwbutler.updates;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand All @@ -509,7 +509,7 @@
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = Updates/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 1.6.0;
MARKETING_VERSION = 1.6.1;
MODULE_NAME = ExampleApp;
PRODUCT_BUNDLE_IDENTIFIER = com.rwbutler.updates;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down
20 changes: 10 additions & 10 deletions Example/Updates/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@ import UIKit
import Updates

class ViewController: UIViewController {

@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
@IBOutlet weak var versionLabel: UILabel!

override func viewDidLoad() {
super.viewDidLoad()
activityIndicator.startAnimating()
configureUpdates()
configureLabels()
observeAppVersionDidChange()
}

override func viewDidAppear(_ animated: Bool) {
Updates.configurationURL = Bundle.main.url(forResource: "Updates", withExtension: "json")
Updates.checkForUpdates { result in
Expand All @@ -33,41 +33,41 @@ class ViewController: UIViewController {
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}

// MARK: - Notifications

private func observeAppVersionDidChange() {
NotificationCenter.default.addObserver(self, selector: #selector(appDidInstall),
name: .appDidInstall, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(appVersionDidChange),
name: .appVersionDidChange, object: nil)
}

@objc func appDidInstall(_ notification: Notification) {
print("App installed.")
}

@objc func appVersionDidChange(_ notification: Notification) {
print("App version changed.")
}

}

private extension ViewController {

func configureLabels() {
let versionString: String? = Updates.versionString
let buildString: String? = Updates.buildString
if let version = versionString, let build = buildString {
versionLabel.text = "App version: \(version)(\(build))"
}
}

func configureUpdates() {
// - Add custom configuration here if needed -
// Updates.bundleIdentifier = ""
// Updates.countryCode = ""
// Updates.versionString = ""
}

}
2 changes: 1 addition & 1 deletion Updates.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'Updates'
s.version = '1.5.0'
s.version = '1.6.1'
s.swift_version = '5.0'
s.summary = 'Updates is a framework for automatically detecting app updates and seamlessly prompting users to update.'
s.description = <<-DESC
Expand Down
2 changes: 1 addition & 1 deletion Updates/Classes/Core/Model/NotificationMode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public enum NotificationMode: String, Codable {
case thrice
case always
case withoutAvailableUpdate = "without-available-update"

var notificationCount: Int {
switch self {
case .never:
Expand Down
52 changes: 26 additions & 26 deletions Updates/Classes/Core/Updates.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ import Foundation
import StoreKit

public class Updates {

// MARK: Global State

public static var configurationType: ConfigurationType = {
for configurationType in ConfigurationType.allCases where bundledConfigurationURL(configurationType) != nil {
return configurationType
}
return .json // Default configuration type.
}()

/// Defaults configuration URL to bundled configuration and detects configuration type when set.
public static var configurationURL: URL? = bundledConfigurationURL() {
didSet { // detect configuration format by extension
Expand All @@ -32,7 +32,7 @@ public class Updates {
}
}
}

public static var appStoreId: String? {
didSet {
guard appStoreURL == nil, let appStoreId = appStoreId, let productName = productName else {
Expand All @@ -41,9 +41,9 @@ public class Updates {
appStoreURL = appStoreURL(appStoreId: appStoreId, productName: productName)
}
}

public static var appStoreURL: URL?

/// Returns the URL to open the app with the specified identifier in the App Store.
/// - Parameters:
/// - appStoreId: The app store identifier specified as a String.
Expand All @@ -53,13 +53,13 @@ public class Updates {
Updates.appStoreId = appStoreId
return appStoreURL
}

public static let buildString: String? = Bundle.main.infoDictionary?[kCFBundleVersionKey as String] as? String

public static var bundleIdentifier: String? = Bundle.main.bundleIdentifier

public static var comparingVersions: VersionComparator = .patch

public static var countryCode: String? = {
let currentBundle = Bundle(for: Updates.self)
if #available(iOS 13.0, macCatalyst 13.0, *),
Expand All @@ -73,29 +73,29 @@ public class Updates {
return Locale.current.regionCode
}
}()

public static var newVersionString: String?

public static var notifying: NotificationMode = .once

public static var minimumOSVersion: String?

public static var minimumOptionalAppVersion: String?

public static var minimumRequiredAppVersion: String?

public static let productName: String? = Bundle.main.infoDictionary?["CFBundleDisplayName"] as? String

public static var releaseNotes: String?

public static var updateType: UpdateType = .soft

public static var updatingMode: UpdatingMode = .automatically

public static var useStoreKit = true

public static var versionString: String? = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String

public static func checkForUpdates(currentOSVersion: String, completion: @escaping (UpdatesResult) -> Void) {
guard let configURL = configurationURL, let cachedConfigURL = cachedConfigurationURL else {
checkForUpdates(
Expand Down Expand Up @@ -126,7 +126,7 @@ public class Updates {
}
}
}

private static func checkForUpdates(configuration: ConfigurationResult,
operatingSystemVersion: String,
completion: @escaping (UpdatesResult) -> Void) {
Expand All @@ -152,7 +152,7 @@ public class Updates {
}
updatesService.checkForUpdates(completion: completion)
}

/// Warning: Use either this method or `checkForUpdates` but never both as whichever is called first will return the
/// correct result. If using `checkForUpdates` then an `AppUpdatedResult` is returned as part of the
/// `UpdatesResult` object.
Expand All @@ -173,7 +173,7 @@ public class Updates {
)
completion(isUpdated)
}

private static func programmaticConfiguration() -> ConfigurationResult {
return ConfigurationResult(
appStoreId: appStoreId,
Expand All @@ -190,5 +190,5 @@ public class Updates {
latestVersion: versionString
)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
import Foundation

struct ITunesSearchAPIService: AppMetadataService {

/// URL for invocation of iTunes Search API.
private let iTunesSearchAPIURL: URL

/// Parses iTunes Search API responses.
private let parsingService = ITunesSearchJSONParsingService()

init?(bundleIdentifier: String, countryCode: String) {
let lowercasedCountryCode = countryCode.lowercased()
let urlString = "http://itunes.apple.com/lookup?bundleId=\(bundleIdentifier)&country=\(lowercasedCountryCode)"
Expand All @@ -23,7 +23,7 @@ struct ITunesSearchAPIService: AppMetadataService {
}
self.iTunesSearchAPIURL = url
}

/// Parses data returned by the iTunes Search API.
private func parseConfiguration(data: Data) -> ParsingServiceResult? {
switch parsingService.parse(data) {
Expand All @@ -33,7 +33,7 @@ struct ITunesSearchAPIService: AppMetadataService {
return nil
}
}

func fetchAppMetadata(_ completion: @escaping (AppMetadataResult) -> Void) {
DispatchQueue.global(qos: .background).async {
guard let apiData = try? Data(contentsOf: self.iTunesSearchAPIURL) else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
import Foundation

struct ITunesSearchJSONParsingService: ParsingService {

// swiftlint:disable:next type_name
typealias T = ITunesSearchAPIResult

func parse(_ data: Data) -> Result<ITunesSearchAPIResult, ParsingError> {
guard !data.isEmpty else {
return .failure(.emptyPayload)
Expand All @@ -32,5 +32,5 @@ struct ITunesSearchJSONParsingService: ParsingService {
}
return .success(result)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import Foundation

struct ConfigurationResult: Codable {

enum CodingKeys: String, CodingKey {
case appStoreId = "app-store-id"
case build
Expand All @@ -23,7 +23,7 @@ struct ConfigurationResult: Codable {
case updatingMode = "check-for"
case version
}

let appStoreId: String?
let bundleVersion: String?
let buildString: String?
Expand All @@ -36,7 +36,7 @@ struct ConfigurationResult: Codable {
let updatingMode: UpdatingMode
let latestVersion: String?
let updateType: UpdateType

init(
appStoreId: String?,
buildString: String?,
Expand Down Expand Up @@ -64,7 +64,7 @@ struct ConfigurationResult: Codable {
self.updatingMode = updatingMode
self.latestVersion = latestVersion
}

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.appStoreId = try? container.decode(String.self, forKey: .appStoreId)
Expand All @@ -84,7 +84,7 @@ struct ConfigurationResult: Codable {
?? Updates.updatingMode
self.latestVersion = try? container.decode(String.self, forKey: .version)
}

func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(appStoreId, forKey: .appStoreId)
Expand All @@ -97,11 +97,11 @@ struct ConfigurationResult: Codable {
try container.encode(updatingMode, forKey: .updatingMode)
try container.encode(latestVersion, forKey: .version)
}

}

extension ConfigurationResult {

func mutableCopy(with apiResult: ITunesSearchAPIResult) -> ConfigurationResult {
let mergedReleaseNotes = apiResult.releaseNotes ?? releaseNotes
return ConfigurationResult(
Expand All @@ -119,5 +119,5 @@ extension ConfigurationResult {
latestVersion: apiResult.version
)
}

}
18 changes: 18 additions & 0 deletions Updates/Classes/Services/App Metadata/Model/UpdatesResult.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,22 @@ public struct Update {
public let releaseNotes: String?
public let shouldNotify: Bool
public let updateType: UpdateType

public init(
appStoreId: String?,
appStoreURL: URL?,
isUpdated: AppUpdatedResult,
newVersionString: String,
releaseNotes: String?,
shouldNotify: Bool,
updateType: UpdateType
) {
self.appStoreId = appStoreId
self.appStoreURL = appStoreURL
self.isUpdated = isUpdated
self.newVersionString = newVersionString
self.releaseNotes = releaseNotes
self.shouldNotify = shouldNotify
self.updateType = updateType
}
}
Loading

0 comments on commit 8890afb

Please sign in to comment.