ContentView.swift 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. // Copyright 2020 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. import SwiftUI
  15. import FirebaseMLModelDownloader
  16. struct ContentView: View {
  17. var downloadTotal: Float = 1.0
  18. @ObservedObject var downloader = Downloader()
  19. private var buttons: some View {
  20. VStack(spacing: 10) {
  21. Button(action: downloader.downloadModelHelper(downloadType: .localModel), label: {
  22. Text("Local Model")
  23. })
  24. .buttonStyle(CustomDownloadButtonStyle())
  25. Button(
  26. action: downloader.downloadModelHelper(downloadType: .localModelUpdateInBackground),
  27. label: {
  28. Text("Local Model (Background Update)")
  29. }
  30. )
  31. .buttonStyle(CustomDownloadButtonStyle())
  32. Button(action: downloader.downloadModelHelper(downloadType: .latestModel), label: {
  33. Text("Latest Model")
  34. })
  35. .buttonStyle(CustomDownloadButtonStyle())
  36. Button(action: downloader.listModelHelper(), label: {
  37. Text("List Models")
  38. })
  39. .buttonStyle(CustomListButtonStyle())
  40. .padding()
  41. Button(action: downloader.deleteModelHelper(), label: {
  42. Text("Delete Model")
  43. })
  44. .buttonStyle(CustomDeleteButtonStyle())
  45. }
  46. }
  47. private var download: some View {
  48. VStack {
  49. if downloader.downloadProgress >= downloadTotal {
  50. Text("Model downloaded!")
  51. .foregroundColor(.green)
  52. } else {
  53. Text("Model already on device!")
  54. .foregroundColor(.green)
  55. }
  56. Text("Model saved at \(downloader.filePath).")
  57. .foregroundColor(.gray)
  58. .fixedSize(horizontal: false, vertical: /*@START_MENU_TOKEN@*/true/*@END_MENU_TOKEN@*/)
  59. .font(.footnote)
  60. }
  61. }
  62. private var delete: some View {
  63. Text("Model deleted.")
  64. .foregroundColor(.purple)
  65. .padding()
  66. }
  67. private var list: some View {
  68. VStack {
  69. Text("These models are currently on device.")
  70. .foregroundColor(.green)
  71. List(downloader.modelNames, id: \.self) { name in
  72. Text(name)
  73. .foregroundColor(.pink)
  74. .padding()
  75. }
  76. }
  77. }
  78. var body: some View {
  79. VStack(spacing: 10) {
  80. Text("Download Model")
  81. .font(.title)
  82. TextField("Enter model name", text: $downloader.modelName)
  83. .frame(width: 200, height: 100)
  84. .clipped()
  85. .autocapitalization(.none)
  86. .textFieldStyle(RoundedBorderTextFieldStyle())
  87. buttons
  88. ProgressView("Downloading...", value: downloader.downloadProgress, total: downloadTotal)
  89. .progressViewStyle(CustomProgressViewStyle(progress: downloader.downloadProgress,
  90. total: downloadTotal))
  91. if downloader.isDownloaded {
  92. download
  93. }
  94. if downloader.isDeleted {
  95. delete
  96. }
  97. if downloader.modelNames.count > 0 {
  98. list
  99. }
  100. if downloader.isError {
  101. Text(downloader.error)
  102. }
  103. }
  104. }
  105. }
  106. struct ContentView_Previews: PreviewProvider {
  107. static var previews: some View {
  108. ContentView()
  109. }
  110. }
  111. struct CustomProgressViewStyle: ProgressViewStyle {
  112. var downloadProgressColor: Color = .blue
  113. var downloadCompletecolor: Color = .green
  114. var progress: Float
  115. var total: Float
  116. func makeBody(configuration: Configuration) -> some View {
  117. ProgressView(configuration)
  118. .padding(.horizontal, 30)
  119. .opacity(progress > 0 && progress < total ? 0.8 : 0.0)
  120. }
  121. }
  122. struct CustomDownloadButtonStyle: ButtonStyle {
  123. func makeBody(configuration: Configuration) -> some View {
  124. configuration.label
  125. .padding(5)
  126. .foregroundColor(.white)
  127. .background(configuration.isPressed ? Color.orange : Color.blue)
  128. .shadow(radius: 5)
  129. }
  130. }
  131. struct CustomListButtonStyle: ButtonStyle {
  132. func makeBody(configuration: Configuration) -> some View {
  133. configuration.label
  134. .padding(5)
  135. .foregroundColor(.white)
  136. .background(configuration.isPressed ? Color.orange : Color.green)
  137. .shadow(radius: 5)
  138. }
  139. }
  140. struct CustomDeleteButtonStyle: ButtonStyle {
  141. func makeBody(configuration: Configuration) -> some View {
  142. configuration.label
  143. .padding(5)
  144. .foregroundColor(.white)
  145. .background(configuration.isPressed ? Color.orange : Color.red)
  146. .shadow(radius: 5)
  147. }
  148. }