Added more robust app documentation. Started working on an issue where entering zero as the first number in the Distance text field causes the app to crash.
This commit is contained in:
parent
7d6643112d
commit
b6677c2053
7 changed files with 108 additions and 41 deletions
|
|
@ -18,6 +18,7 @@
|
||||||
850F8028285437500094580D /* aiden.moore.states.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 850F8024285437500094580D /* aiden.moore.states.jpg */; };
|
850F8028285437500094580D /* aiden.moore.states.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 850F8024285437500094580D /* aiden.moore.states.jpg */; };
|
||||||
850F8029285437500094580D /* isaac.greene.clouds.heic in Resources */ = {isa = PBXBuildFile; fileRef = 850F8025285437500094580D /* isaac.greene.clouds.heic */; };
|
850F8029285437500094580D /* isaac.greene.clouds.heic in Resources */ = {isa = PBXBuildFile; fileRef = 850F8025285437500094580D /* isaac.greene.clouds.heic */; };
|
||||||
850F802A285437500094580D /* jake.zimmerman.group.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 850F8026285437500094580D /* jake.zimmerman.group.jpg */; };
|
850F802A285437500094580D /* jake.zimmerman.group.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 850F8026285437500094580D /* jake.zimmerman.group.jpg */; };
|
||||||
|
859298C928592F1F00D9D6CB /* Documentation.docc in Sources */ = {isa = PBXBuildFile; fileRef = 859298C828592F1F00D9D6CB /* Documentation.docc */; };
|
||||||
85AAA0D627FA2DD600F4B9A1 /* SplitsApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85AAA0D527FA2DD600F4B9A1 /* SplitsApp.swift */; };
|
85AAA0D627FA2DD600F4B9A1 /* SplitsApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85AAA0D527FA2DD600F4B9A1 /* SplitsApp.swift */; };
|
||||||
85AAA0D827FA2DD600F4B9A1 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85AAA0D727FA2DD600F4B9A1 /* ContentView.swift */; };
|
85AAA0D827FA2DD600F4B9A1 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85AAA0D727FA2DD600F4B9A1 /* ContentView.swift */; };
|
||||||
85AAA0DA27FA2DDA00F4B9A1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 85AAA0D927FA2DDA00F4B9A1 /* Assets.xcassets */; };
|
85AAA0DA27FA2DDA00F4B9A1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 85AAA0D927FA2DDA00F4B9A1 /* Assets.xcassets */; };
|
||||||
|
|
@ -39,6 +40,7 @@
|
||||||
850F8024285437500094580D /* aiden.moore.states.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = aiden.moore.states.jpg; path = Assets.xcassets/aiden.moore.states.jpg; sourceTree = "<group>"; };
|
850F8024285437500094580D /* aiden.moore.states.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = aiden.moore.states.jpg; path = Assets.xcassets/aiden.moore.states.jpg; sourceTree = "<group>"; };
|
||||||
850F8025285437500094580D /* isaac.greene.clouds.heic */ = {isa = PBXFileReference; lastKnownFileType = file; name = isaac.greene.clouds.heic; path = Assets.xcassets/isaac.greene.clouds.heic; sourceTree = "<group>"; };
|
850F8025285437500094580D /* isaac.greene.clouds.heic */ = {isa = PBXFileReference; lastKnownFileType = file; name = isaac.greene.clouds.heic; path = Assets.xcassets/isaac.greene.clouds.heic; sourceTree = "<group>"; };
|
||||||
850F8026285437500094580D /* jake.zimmerman.group.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = jake.zimmerman.group.jpg; path = Assets.xcassets/jake.zimmerman.group.jpg; sourceTree = "<group>"; };
|
850F8026285437500094580D /* jake.zimmerman.group.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = jake.zimmerman.group.jpg; path = Assets.xcassets/jake.zimmerman.group.jpg; sourceTree = "<group>"; };
|
||||||
|
859298C828592F1F00D9D6CB /* Documentation.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = Documentation.docc; sourceTree = "<group>"; };
|
||||||
85AAA0D227FA2DD600F4B9A1 /* Splits.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Splits.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
85AAA0D227FA2DD600F4B9A1 /* Splits.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Splits.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
85AAA0D527FA2DD600F4B9A1 /* SplitsApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitsApp.swift; sourceTree = "<group>"; };
|
85AAA0D527FA2DD600F4B9A1 /* SplitsApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitsApp.swift; sourceTree = "<group>"; };
|
||||||
85AAA0D727FA2DD600F4B9A1 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
85AAA0D727FA2DD600F4B9A1 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||||
|
|
@ -80,6 +82,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
85AAA0D527FA2DD600F4B9A1 /* SplitsApp.swift */,
|
85AAA0D527FA2DD600F4B9A1 /* SplitsApp.swift */,
|
||||||
|
859298C828592F1F00D9D6CB /* Documentation.docc */,
|
||||||
8502250D27FA5D0800FE8E95 /* ChangeLogData.swift */,
|
8502250D27FA5D0800FE8E95 /* ChangeLogData.swift */,
|
||||||
85AAA0D727FA2DD600F4B9A1 /* ContentView.swift */,
|
85AAA0D727FA2DD600F4B9A1 /* ContentView.swift */,
|
||||||
850062C82802328F0095F121 /* TabViewData.swift */,
|
850062C82802328F0095F121 /* TabViewData.swift */,
|
||||||
|
|
@ -195,6 +198,7 @@
|
||||||
8502250E27FA5D0800FE8E95 /* ChangeLogData.swift in Sources */,
|
8502250E27FA5D0800FE8E95 /* ChangeLogData.swift in Sources */,
|
||||||
850F8014284A7F6A0094580D /* DocsView.swift in Sources */,
|
850F8014284A7F6A0094580D /* DocsView.swift in Sources */,
|
||||||
850F8016284A815C0094580D /* KnownIssues.swift in Sources */,
|
850F8016284A815C0094580D /* KnownIssues.swift in Sources */,
|
||||||
|
859298C928592F1F00D9D6CB /* Documentation.docc in Sources */,
|
||||||
85AAA0E827FA2F1600F4B9A1 /* ChangeLogView.swift in Sources */,
|
85AAA0E827FA2F1600F4B9A1 /* ChangeLogView.swift in Sources */,
|
||||||
85AAA0E627FA2EB100F4B9A1 /* ModalView.swift in Sources */,
|
85AAA0E627FA2EB100F4B9A1 /* ModalView.swift in Sources */,
|
||||||
850F80202853F7790094580D /* LicenseView.swift in Sources */,
|
850F80202853F7790094580D /* LicenseView.swift in Sources */,
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,23 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
// this file will not have comments.
|
|
||||||
// it is considered self-explanatory and best viewed in-app
|
|
||||||
|
|
||||||
struct June2022: View {
|
struct June2022: View {
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ScrollView {
|
ScrollView {
|
||||||
|
//2022-06-14
|
||||||
|
HStack {
|
||||||
|
VStack (alignment: .leading) {
|
||||||
|
Text("2022-06-14")
|
||||||
|
.font(.title2)
|
||||||
|
Text("Version Prerelease Build LVSXT10a.3\n")
|
||||||
|
.font(.footnote)
|
||||||
|
Text("\u{2022} Optimized some code to allow for future development\n\u{2022} Starting on fixing an issue where putting a zero as the first number in the Distance field causes the app to crash\n\u{2022} Partially added more robust app documentation")
|
||||||
|
}
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.padding(30)
|
||||||
|
|
||||||
//2022-06-11
|
//2022-06-11
|
||||||
HStack {
|
HStack {
|
||||||
VStack (alignment: .leading) {
|
VStack (alignment: .leading) {
|
||||||
|
|
@ -43,7 +54,7 @@ struct June2022: View {
|
||||||
VStack (alignment: .leading) {
|
VStack (alignment: .leading) {
|
||||||
Text("2022-06-09")
|
Text("2022-06-09")
|
||||||
.font(.title2)
|
.font(.title2)
|
||||||
Text("Version Prerelease LVSXT10c.2\n")
|
Text("Version Prerelease Build LVSXT10c.2\n")
|
||||||
.font(.footnote)
|
.font(.footnote)
|
||||||
Text("\u{2022} Worked on a simple login page to view contact info\n\t\u{2022} Spent *way* too long on it")
|
Text("\u{2022} Worked on a simple login page to view contact info\n\t\u{2022} Spent *way* too long on it")
|
||||||
}
|
}
|
||||||
|
|
@ -63,6 +74,7 @@ struct June2022: View {
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
.padding(30)
|
.padding(30)
|
||||||
|
|
||||||
//2022-06-05
|
//2022-06-05
|
||||||
HStack {
|
HStack {
|
||||||
VStack (alignment: .leading) {
|
VStack (alignment: .leading) {
|
||||||
|
|
@ -70,9 +82,11 @@ struct June2022: View {
|
||||||
.font(.title2)
|
.font(.title2)
|
||||||
Text("Version Prerelease Build LVSXT10d.3\n")
|
Text("Version Prerelease Build LVSXT10d.3\n")
|
||||||
.font(.footnote)
|
.font(.footnote)
|
||||||
Text("\u{2022} Started work on converting the pace to a more understandable format\n\u{2022} ")
|
Text("\u{2022} Started work on converting the pace to a more understandable format")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.padding(30)
|
||||||
|
|
||||||
//2022-06-04
|
//2022-06-04
|
||||||
HStack {
|
HStack {
|
||||||
VStack (alignment: .leading) {
|
VStack (alignment: .leading) {
|
||||||
|
|
@ -118,6 +132,7 @@ struct June2022: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// done adding content to these
|
||||||
struct May2022: View {
|
struct May2022: View {
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ScrollView {
|
ScrollView {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
/// Creates the primary tab of ``SplitsApp``
|
||||||
|
///
|
||||||
|
/// e
|
||||||
struct ContentView: View {
|
struct ContentView: View {
|
||||||
@FocusState private var nameIsFocused: Bool
|
@FocusState private var nameIsFocused: Bool
|
||||||
var SISystem = ["km","mi"]
|
var SISystem = ["km","mi"]
|
||||||
|
|
@ -101,8 +104,10 @@ struct PaceResults: View {
|
||||||
|
|
||||||
let multiplier = (selectedSystem == "mi" ? 1.609344 : 0.6213711922)
|
let multiplier = (selectedSystem == "mi" ? 1.609344 : 0.6213711922)
|
||||||
let notSelectedSystem = (selectedSystem == "km" ? "mi" : "km")
|
let notSelectedSystem = (selectedSystem == "km" ? "mi" : "km")
|
||||||
|
let convertedDistanceString:String = {
|
||||||
let convertedDistance = distanceDub * multiplier
|
let convertedDistance = distanceDub * multiplier
|
||||||
let convertedDistanceString = (distance == "" ? "" : String(format: "%.2f", convertedDistance))
|
return (distance == "" || distance.starts(with: "0") ? "0" : String(format: "%.3f", convertedDistance))
|
||||||
|
}()
|
||||||
|
|
||||||
let convertedSeconds:Double = (Double(timeSeconds) ?? 0) * (1.6666666666666666666666666)
|
let convertedSeconds:Double = (Double(timeSeconds) ?? 0) * (1.6666666666666666666666666)
|
||||||
let timeSecondsInt:Int = Int(timeSeconds) ?? 0
|
let timeSecondsInt:Int = Int(timeSeconds) ?? 0
|
||||||
|
|
@ -141,22 +146,27 @@ struct PaceResults: View {
|
||||||
// a single value in terms of minutes, so that 1:08:45
|
// a single value in terms of minutes, so that 1:08:45
|
||||||
// becomes 68.75 which is a nice number we can do math on
|
// becomes 68.75 which is a nice number we can do math on
|
||||||
// and this number is never directly seen by the user
|
// and this number is never directly seen by the user
|
||||||
let pace = actualTime / distanceDub
|
|
||||||
let paceOpposite = (selectedSystem == "km" ? (pace * 1.609344) : (pace * 0.6213711922))
|
|
||||||
|
|
||||||
|
let pace = actualTime / distanceDub
|
||||||
|
|
||||||
|
let paceFormatted:String = {
|
||||||
let paceSeconds = pace.truncatingRemainder(dividingBy: 1.0)
|
let paceSeconds = pace.truncatingRemainder(dividingBy: 1.0)
|
||||||
let paceMinutes = (pace.truncatingRemainder(dividingBy: 60.0) - paceSeconds)
|
let paceMinutes = (pace.truncatingRemainder(dividingBy: 60.0) - paceSeconds)
|
||||||
let paceHours = String(format: "%.0f", ((pace - paceMinutes) / 60))
|
let paceHours = String(format: "%.0f", ((pace - paceMinutes) / 60))
|
||||||
let reConvertedSeconds = (paceSeconds / 1.666666666666666666) * 100
|
let reConvertedSeconds = (paceSeconds / 1.666666666666666666) * 100
|
||||||
|
|
||||||
let properTimeMS = String(format: "%02d:%02d", Int(paceMinutes), Int(reConvertedSeconds.rounded()))
|
let properTimeMS = String(format: "%02d:%02d", Int(paceMinutes), Int(reConvertedSeconds.rounded()))
|
||||||
|
return (pace >= 60 ? "\(paceHours):\(properTimeMS)" : "\(properTimeMS)")
|
||||||
|
}()
|
||||||
|
|
||||||
|
let paceFormattedOpposite:String = {
|
||||||
|
let paceOpposite = (selectedSystem == "km" ? (pace * 1.609344) : (pace * 0.6213711922))
|
||||||
let paceSecondsOpposite = paceOpposite.truncatingRemainder(dividingBy: 1.0)
|
let paceSecondsOpposite = paceOpposite.truncatingRemainder(dividingBy: 1.0)
|
||||||
let paceMinutesOpposite = (paceOpposite.truncatingRemainder(dividingBy: 60.0) - paceSecondsOpposite)
|
let paceMinutesOpposite = (paceOpposite.truncatingRemainder(dividingBy: 60.0) - paceSecondsOpposite)
|
||||||
let paceHoursOpposite = String(format: "%.0f", ((paceOpposite - paceMinutesOpposite) / 60))
|
let paceHoursOpposite = String(format: "%.0f", ((paceOpposite - paceMinutesOpposite) / 60))
|
||||||
let reConvertedSecondsOpposite = (paceSecondsOpposite / 1.666666666666666666) * 100
|
let reConvertedSecondsOpposite = (paceSecondsOpposite / 1.666666666666666666) * 100
|
||||||
|
|
||||||
let properTimeMSOpposite = String(format: "%02d:%02d", Int(paceMinutesOpposite), Int(reConvertedSecondsOpposite.rounded()))
|
let properTimeMSOpposite = String(format: "%02d:%02d", Int(paceMinutesOpposite), Int(reConvertedSecondsOpposite.rounded()))
|
||||||
|
return (paceOpposite >= 60 ? "\(paceHoursOpposite):\(properTimeMSOpposite)" : "\(properTimeMSOpposite)")
|
||||||
|
}()
|
||||||
|
|
||||||
//let paceString:String = String(format: "%.2f", pace)
|
//let paceString:String = String(format: "%.2f", pace)
|
||||||
let totalHours:Double = Double(timeMinutesToHours) + (Double(timeHours) ?? 0)
|
let totalHours:Double = Double(timeMinutesToHours) + (Double(timeHours) ?? 0)
|
||||||
|
|
@ -164,9 +174,7 @@ struct PaceResults: View {
|
||||||
// and the hours calculated in the previous section
|
// and the hours calculated in the previous section
|
||||||
// and adds them together to get our total number of hours.
|
// and adds them together to get our total number of hours.
|
||||||
let hoursFormatted:String = String(format: "%.0f", totalHours)
|
let hoursFormatted:String = String(format: "%.0f", totalHours)
|
||||||
let paceFormatted:String = (pace >= 60 ? "\(paceHours):\(properTimeMS)" : "\(properTimeMS)")
|
|
||||||
|
|
||||||
let paceFormattedOpposite:String = (paceOpposite >= 60 ? "\(paceHoursOpposite):\(properTimeMSOpposite)" : "\(properTimeMSOpposite)")
|
|
||||||
|
|
||||||
let leadingZeros:String = String(format: "%02d:%02d", timeMinutesUnderSixty, timeSecondsUnderSixty)
|
let leadingZeros:String = String(format: "%02d:%02d", timeMinutesUnderSixty, timeSecondsUnderSixty)
|
||||||
// this takes the minutes and the seconds and adds leading
|
// this takes the minutes and the seconds and adds leading
|
||||||
|
|
@ -175,7 +183,7 @@ struct PaceResults: View {
|
||||||
// the people this app is intended for, will understand
|
// the people this app is intended for, will understand
|
||||||
|
|
||||||
HStack {
|
HStack {
|
||||||
VStack {
|
VStack (alignment: .leading) {
|
||||||
Text("\(distance)\(selectedSystem)")
|
Text("\(distance)\(selectedSystem)")
|
||||||
Text("\(convertedDistanceString)\(notSelectedSystem)")
|
Text("\(convertedDistanceString)\(notSelectedSystem)")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,25 @@ import LocalAuthentication
|
||||||
// the reader has a basic understanding of
|
// the reader has a basic understanding of
|
||||||
// Swift and/or SwiftUI.
|
// Swift and/or SwiftUI.
|
||||||
|
|
||||||
|
/// The system username for the app
|
||||||
|
/// - Note: This is not a secure way to do it
|
||||||
|
/// or in any way good practice
|
||||||
|
/// but this is mainly to test out `SecureField`
|
||||||
let username = "admin"
|
let username = "admin"
|
||||||
|
|
||||||
|
/// The system password associated with ``username``
|
||||||
|
///
|
||||||
|
/// I'm thinking about hashing them, but that would take work.
|
||||||
|
///
|
||||||
|
/// It would be more secure though.
|
||||||
|
/// - Note: Just as with `username` you should not define
|
||||||
|
/// these unencrypted like they are right now.
|
||||||
let password = "123"
|
let password = "123"
|
||||||
|
|
||||||
|
/// Holds the views and login for the Docs tab in-app
|
||||||
|
///
|
||||||
|
/// Mostly just a long list of sections and calling views
|
||||||
|
/// - Note: New views are best called in this `struct`
|
||||||
struct DocsView: View {
|
struct DocsView: View {
|
||||||
enum Field: Hashable {
|
enum Field: Hashable {
|
||||||
case username
|
case username
|
||||||
|
|
@ -46,8 +62,8 @@ struct DocsView: View {
|
||||||
}
|
}
|
||||||
Section(header: Text("App Information")) {
|
Section(header: Text("App Information")) {
|
||||||
NavigationLink("Software License", destination: LicenseView())
|
NavigationLink("Software License", destination: LicenseView())
|
||||||
Text("Version: Release Candidate 2 (1.0.0)")
|
Text("Version: Prerelease Build LVSXT10a.3")
|
||||||
Text("Release date: 2022-06-11")
|
Text("Release date: 2022-06-14")
|
||||||
Text("Start date: 2022-03-25")
|
Text("Start date: 2022-03-25")
|
||||||
Link("Built with SwiftUI \(Image(systemName: "swift"))", destination: URL(string: "https://developer.apple.com/xcode/swiftui")!)
|
Link("Built with SwiftUI \(Image(systemName: "swift"))", destination: URL(string: "https://developer.apple.com/xcode/swiftui")!)
|
||||||
}
|
}
|
||||||
|
|
@ -60,21 +76,21 @@ struct DocsView: View {
|
||||||
isUnlocked = false
|
isUnlocked = false
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if !isUnlocked {
|
|
||||||
Button("Log in with biometrics") {
|
Button("Log in with biometrics") {
|
||||||
authenticate()
|
authenticate()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
SecureField("Username", text: $user)
|
SecureField("Username", text: $user)
|
||||||
.keyboardType(.alphabet)
|
.keyboardType(.alphabet)
|
||||||
.textContentType(.username)
|
.textContentType(.username)
|
||||||
.submitLabel(.next)
|
.submitLabel(.next)
|
||||||
.focused($focusedField, equals: .username)
|
.focused($focusedField, equals: .username)
|
||||||
|
.textContentType(.username)
|
||||||
SecureField("Password", text: $pass)
|
SecureField("Password", text: $pass)
|
||||||
.keyboardType(.numbersAndPunctuation)
|
.keyboardType(.numbersAndPunctuation)
|
||||||
.textContentType(.password)
|
.textContentType(.password)
|
||||||
.submitLabel(.done)
|
.submitLabel(.done)
|
||||||
.focused($focusedField, equals: .password)
|
.focused($focusedField, equals: .password)
|
||||||
|
.textContentType(.password)
|
||||||
if checkPassword() {
|
if checkPassword() {
|
||||||
NavigationLink("Contacts", destination: SecretView())
|
NavigationLink("Contacts", destination: SecretView())
|
||||||
}
|
}
|
||||||
|
|
@ -90,11 +106,19 @@ struct DocsView: View {
|
||||||
default:
|
default:
|
||||||
()
|
()
|
||||||
}
|
}
|
||||||
if (pass == password && user == username) {
|
if checkPassword() {
|
||||||
isUnlocked = true
|
isUnlocked = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Compares the `user` SecureField and the `pass` SecureField against ``username`` and ``password``
|
||||||
|
///
|
||||||
|
/// - Note: come back to this
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// - Returns: `true` if `user` equals `username` *and* `pass` equals `password`, `false` if one or both checks return false.
|
||||||
func checkPassword() -> Bool {
|
func checkPassword() -> Bool {
|
||||||
if (pass == password && user == username) {
|
if (pass == password && user == username) {
|
||||||
return true
|
return true
|
||||||
|
|
@ -102,11 +126,15 @@ struct DocsView: View {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func checkIfUnlocked() {
|
|
||||||
if !isUnlocked {
|
/// Checks wether the user can use biometrics to sign in
|
||||||
authenticate()
|
/// and (if true) prompts the user to sign with either FaceID or TouchID
|
||||||
}
|
/// depending on the device.
|
||||||
}
|
///
|
||||||
|
/// If the prompt was shown, and the user authenticated correctly
|
||||||
|
/// `isUnlocked` is set to `true`
|
||||||
|
///
|
||||||
|
/// - Note: `authenticate()` has to be called to show the sign-in sheet
|
||||||
func authenticate() {
|
func authenticate() {
|
||||||
let context = LAContext()
|
let context = LAContext()
|
||||||
var error: NSError?
|
var error: NSError?
|
||||||
|
|
|
||||||
14
Splits/Documentation.docc/Documentation.md
Normal file
14
Splits/Documentation.docc/Documentation.md
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
# ``Splits``
|
||||||
|
|
||||||
|
Splits is a revolutionary new app to calculate paces.
|
||||||
|
It takes a value, in kilometers or miles, and converts
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
<!--@START_MENU_TOKEN@-->Text<!--@END_MENU_TOKEN@-->
|
||||||
|
|
||||||
|
## Topics
|
||||||
|
|
||||||
|
### Getting Started
|
||||||
|
|
||||||
|
- <!--@START_MENU_TOKEN@-->``Symbol``<!--@END_MENU_TOKEN@-->
|
||||||
|
|
@ -25,10 +25,7 @@ struct HighPriority: View {
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ScrollView {
|
ScrollView {
|
||||||
VStack {
|
VStack {
|
||||||
Image(systemName: "checkmark.shield.fill")
|
Text("\u{2022} Putting a zero as the first number in the Distance text field causes the app to crash\n\t\u{2022} **Workaround:** Just don't put zero first. You can still use decimals (like .7km and .24mi)")
|
||||||
.resizable()
|
|
||||||
.aspectRatio(contentMode: .fit)
|
|
||||||
.frame(width: 70)
|
|
||||||
}
|
}
|
||||||
.padding(30)
|
.padding(30)
|
||||||
}
|
}
|
||||||
|
|
@ -55,7 +52,7 @@ struct LowPriority: View {
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ScrollView {
|
ScrollView {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
Text("\u{2022} Space between the equation and explanation in the \"Help\" tab is too large\n\u{2022} App has no custom icon")
|
Text("\u{2022} Space between the equation and explanation in the \"Help\" tab is too large\n\u{2022} App has no custom icon\n\u{2022} In some circumstances, the pace will show xx:60/unit as a pace, when the 60 should equal one minute")
|
||||||
}
|
}
|
||||||
.padding(30)
|
.padding(30)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import SwiftUI
|
||||||
// Swift and/or SwiftUI.
|
// Swift and/or SwiftUI.
|
||||||
|
|
||||||
@main
|
@main
|
||||||
|
/// Builds the main view of the app (``TabViewData``)
|
||||||
struct SplitsApp: App {
|
struct SplitsApp: App {
|
||||||
var body: some Scene {
|
var body: some Scene {
|
||||||
WindowGroup {
|
WindowGroup {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue