Просмотр исходного кода

* Added build expiry info to settings view and logs (#439) by Jamie Keene

* Added a function to grab the embedded profile expiry date and display it in the settings view & exported logs

* Refactor to avoid force unwrapping and a typo fixed, by @Jon-b-m.

---------

Co-authored-by: Jon Mårtensson <jon.m@live.se>
Jon B.M 2 лет назад
Родитель
Сommit
048de16445

+ 2 - 1
FreeAPS/Sources/Application/FreeAPSApp.swift

@@ -1,5 +1,6 @@
 import ActivityKit
 import CoreData
+import Foundation
 import SwiftUI
 import Swinject
 
@@ -53,7 +54,7 @@ import Swinject
     init() {
         debug(
             .default,
-            "iAPS Started: v\(Bundle.main.releaseVersionNumber ?? "")(\(Bundle.main.buildVersionNumber ?? "")) [buildDate: \(Bundle.main.buildDate)]"
+            "iAPS Started: v\(Bundle.main.releaseVersionNumber ?? "")(\(Bundle.main.buildVersionNumber ?? "")) [buildDate: \(Bundle.main.buildDate)] [buildExpires: \(Bundle.main.profileExpiration)]"
         )
         loadServices()
     }

+ 40 - 0
FreeAPS/Sources/Helpers/Bundle+Extensions.swift

@@ -18,4 +18,44 @@ extension Bundle {
         }
         return Date()
     }
+
+    var profileExpiration: String {
+        guard
+            let profilePath = Bundle.main.path(forResource: "embedded", ofType: "mobileprovision"),
+            let profileData = try? Data(contentsOf: URL(fileURLWithPath: profilePath)),
+            // Note: We use `NSString` instead of `String`, because it makes it easier working with regex, ranges, substring etc.
+            let profileNSString = NSString(data: profileData, encoding: String.Encoding.ascii.rawValue)
+        else {
+            print(
+                "WARNING: Could not find or read `embedded.mobileprovision`. If running on Simulator, there are no provisioning profiles."
+            )
+            return "N/A"
+        }
+
+        // NOTE: We have the `[\\W]*?` check to make sure that variations in number of tabs or new lines in the future does not influence the result.
+        guard let regex = try? NSRegularExpression(pattern: "<key>ExpirationDate</key>[\\W]*?<date>(.*?)</date>", options: [])
+        else {
+            print("Warning: Could not create regex.")
+            return "N/A"
+        }
+
+        let regExMatches = regex.matches(
+            in: profileNSString as String,
+            options: [],
+            range: NSRange(location: 0, length: profileNSString.length)
+        )
+
+        // NOTE: range `0` corresponds to the full regex match, so to get the first capture group, we use range `1`
+        guard let rangeOfCapturedGroupForDate = regExMatches.first?.range(at: 1) else {
+            print("Warning: Could not find regex match or capture group.")
+            return "N/A"
+        }
+
+        let dateWithTimeAsString = profileNSString.substring(with: rangeOfCapturedGroupForDate)
+
+        guard let dateAsStringIndex = dateWithTimeAsString.firstIndex(of: "T") else {
+            return ""
+        }
+        return String(dateWithTimeAsString[..<dateAsStringIndex])
+    }
 }

+ 3 - 2
FreeAPS/Sources/Modules/Settings/View/SettingsRootView.swift

@@ -41,8 +41,9 @@ extension Settings {
                     }
                 } header: {
                     Text(
-                        "iAPS v\(state.versionNumber) (\(state.buildNumber))\nBranch: \(state.branch) \(state.copyrightNotice) "
-                    ).textCase(nil)
+                        "iAPS v\(state.versionNumber) (\(state.buildNumber))\nBranch: \(state.branch) \(state.copyrightNotice)\nBuild Expires: \(Bundle.main.profileExpiration)"
+                    )
+                    .textCase(nil)
                 }.listRowBackground(Color.chart)
 
                 Section {