Merge pull request #2773 from keymanapp/fix/ios/online-help-version

fix(ios): fixes broken online-help versioned link
This commit is contained in:
Joshua Horton 2020-03-04 17:26:15 +07:00 • committed by GitHub
commit d0786a9ae7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 105 additions and 27 deletions

View file

@ -195,7 +195,7 @@ public class Manager: NSObject, UIGestureRecognizerDelegate {
log.error("Failed to copy default keyboard from bundle: \(error)")
}
}
Migrations.engineVersion = Version.current
Migrations.engineVersion = Version.latestFeature
if Util.isSystemKeyboard || Storage.active.userDefaults.bool(forKey: Key.keyboardPickerDisplayed) {
isKeymanHelpOn = false

View file

@ -159,7 +159,7 @@ public enum Migrations {
static func updateResources(storage: Storage) {
var lastVersion = engineVersion
if (lastVersion ?? Version.fallback) >= Version.current {
if (lastVersion ?? Version.fallback) >= Version.latestFeature {
// We're either current or have just been downgraded; no need to do modify resources.
// If it's a downgrade, it's near-certainly a testing environment.
return
@ -267,7 +267,7 @@ public enum Migrations {
}
// Store the version we just upgraded to.
storage.userDefaults.lastEngineVersion = Version.current
storage.userDefaults.lastEngineVersion = Version.latestFeature
}
static func migrateUserDefaultsToStructs(storage: Storage) {

View file

@ -11,7 +11,16 @@ import Foundation
/// Dotted-decimal version.
public struct Version: Comparable {
public static let fallback = Version("1.0")!
public static let current = Version("13.0.65")!
public static let latestFeature = Version("13.0.65")!
public static var current: Version {
// TODO: actually update KMEI's version in the bundle during builds, not just the app's.
//let engineInfo = Bundle(for: Manager.self).infoDictionary
// For now, we just rely on the app's version instead.
let engineInfo = Bundle.main.infoDictionary
return Version(engineInfo!["CFBundleVersion"] as! String)!
}
// The Engine first started tracking the 'last loaded version' in 12.0.
public static let freshInstall = Version("0.0")!
@ -27,7 +36,9 @@ public struct Version: Comparable {
public let string: String
public init?(_ string: String) {
let stringComponents = string.components(separatedBy: ".")
let tagComponents = string.components(separatedBy: "-")
let stringComponents = tagComponents[0].components(separatedBy: ".")
var components: [Int] = []
for s in stringComponents {
guard let i = Int(s), i >= 0 else {
@ -40,6 +51,26 @@ public struct Version: Comparable {
self.components = components
}
public init?(_ components: [Int]) {
if components.count == 0 {
return nil
}
var string = ""
for i in components {
guard i >= 0 else {
return nil
}
let dot = (string == "" ? "" : ".")
string = "\(string)\(dot)\(i)"
}
self.string = string
self.components = components // Swift arrays are value types, not reference types!
}
public static func <(lhs: Version, rhs: Version) -> Bool {
let len = max(lhs.components.count, rhs.components.count)
for i in 0..<len {
@ -63,4 +94,13 @@ public struct Version: Comparable {
public var description: String {
return self.string
}
public var majorMinor: Version {
if(self.components.count >= 2) {
return Version([self.components[0], self.components[1]])!
} else {
// If we somehow have just a major version, append a simple '0'.
return Version([self.components[0], 0])!
}
}
}

View file

@ -11,34 +11,72 @@ import XCTest
class VersionTests: XCTestCase {
override func setUp() {
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func setUp() {
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
func testVersionComparison() {
// Simple unit testing for version-comparison logic.
let simpleEarly = Version("11.0")!
let simpleLate = Version("13.0")!
func testStringConstruction() {
let simpleEarly = Version("11.0")
XCTAssertLessThan(simpleEarly, simpleLate)
XCTAssertNotNil(simpleEarly, "Could not construct Version instance from a simple major-minor version string")
let complexEarly1 = Version("11.0.65")!
let complexEarly2 = Version("11.1.1")!
let complexEarly = Version("11.0.65.17.8")
XCTAssertLessThan(complexEarly1, complexEarly2)
XCTAssertNotNil(complexEarly, "Could not process the version string '11.0.65.17.8'")
let complexLate1 = Version("13.0.1")!
let broken = Version("apple.orange")
XCTAssertLessThan(complexEarly2, complexLate1)
XCTAssertLessThan(simpleLate, complexLate1)
XCTAssertNil(broken, "Erroneously constructed Version instance from character-text strings")
let simpleLater = Version("13.1")!
let tagged = Version("14.0.18-alpha-local")
XCTAssertLessThan(complexLate1, simpleLater)
}
XCTAssertNotNil(tagged, "Could not construct Verison instance from a text-tagged version string")
XCTAssertEqual(tagged, Version("14.0.18"), "Did not produce expected version from text-tagged version string")
}
func testVersionComparison() {
// Simple unit testing for version-comparison logic.
let simpleEarly = Version("11.0")!
let simpleLate = Version("13.0")!
XCTAssertLessThan(simpleEarly, simpleLate)
let complexEarly1 = Version("11.0.65")!
let complexEarly2 = Version("11.1.1")!
XCTAssertLessThan(complexEarly1, complexEarly2)
let complexLate1 = Version("13.0.1")!
XCTAssertLessThan(complexEarly2, complexLate1)
XCTAssertLessThan(simpleLate, complexLate1)
let simpleLater = Version("13.1")!
XCTAssertLessThan(complexLate1, simpleLater)
}
func testMajorMinor() {
let simple = Version("12")!
XCTAssertEqual(simple.majorMinor, Version("12.0")!, "Did not append .minor to major-only version")
let complex = Version("11.0.65.17.8")!
XCTAssertEqual(complex.majorMinor, Version("11.0")!, "Did not properly trim off excess version components")
}
func testValidCurrentEngineVersion() {
let version = Version.current
// Do not test on value; this may mismatch with the actual version, since the test host doesn't get
// version number updates from builds.
//
// The key is that it always returns a version value; this is the most likely 'big break' we may see.
XCTAssertNotNil(version, "Could not construct a valid version from value in bundle's plist file")
}
}

View file

@ -61,7 +61,7 @@ class InfoViewController: UIViewController, UIWebViewDelegate {
}
private func loadFromServer() {
let appVersion = Version.current
let appVersion = Version.current.majorMinor
let url = "https://help.keyman.com/products/iphone-and-ipad/\(appVersion.string)/?embed=ios"
webView.loadRequest(URLRequest(url: URL(string: url)!))
log.debug("Info page URL: \(url)")

View file

@ -68,7 +68,7 @@ class SetUpViewController: UIViewController, UIWebViewDelegate {
}
private func loadFromServer() {
let appVersion = Version.current
let appVersion = Version.current.majorMinor
let url = "https://help.keyman.com/products/iphone-and-ipad/\(appVersion.string)"
+ "/installing-system-keyboard.php?embed=ios"
webView.loadRequest(URLRequest(url: URL(string: url)!))