Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SwiftUI performance quickstart #1238

Merged
merged 41 commits into from
Aug 4, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
1f84015
Create performance project
jrcrespoh Jul 19, 2021
60b2ab8
Add tvOS target
jrcrespoh Jul 28, 2021
94e730b
Add Cocoapods workaround for tvOS
jrcrespoh Jul 29, 2021
294cda8
Add preliminary UI and data flow
jrcrespoh Jul 29, 2021
0d075f0
Improved ProcessStatus view
jrcrespoh Jul 29, 2021
f248425
Add initial download functionality
jrcrespoh Jul 29, 2021
02be1e4
Add image classification functionality
jrcrespoh Jul 30, 2021
eb6b37b
Add Performance trace
jrcrespoh Jul 30, 2021
efb9929
Add ImageView toolbar
jrcrespoh Jul 30, 2021
9802f21
Fix import error
jrcrespoh Jul 30, 2021
60a9b63
Update Podfile
jrcrespoh Jul 30, 2021
734c598
Remove ImageView nagivationTitle
jrcrespoh Jul 30, 2021
8b39c95
Add CI tests
jrcrespoh Jul 30, 2021
ab88dc7
Fix CI
jrcrespoh Jul 30, 2021
6972d5d
Fix CI
jrcrespoh Jul 30, 2021
e9e36b6
Fix CI
jrcrespoh Jul 30, 2021
deb174e
Update performance.yml
jrcrespoh Jul 30, 2021
d7961c7
Update performance.yml
jrcrespoh Jul 30, 2021
7eecffa
Fix type error
jrcrespoh Jul 30, 2021
ea516ac
Update performance.yml
jrcrespoh Jul 31, 2021
6ef3280
Add tvOS CI build and test
jrcrespoh Jul 31, 2021
62426ca
Remove macOS target & fix tvOS deployment target
jrcrespoh Jul 31, 2021
5303e14
Remove macOS target from Podfile
jrcrespoh Jul 31, 2021
a2d6d38
Clarify CI build vs test
jrcrespoh Jul 31, 2021
3834426
Fix tvOS pod dependencies
jrcrespoh Aug 2, 2021
64353e1
Add project schemes
jrcrespoh Aug 2, 2021
df45378
Add GoogleService-Info.plist reference
jrcrespoh Aug 2, 2021
210a14c
Fix enforce build order
jrcrespoh Aug 2, 2021
05a9012
Testing on CI
jrcrespoh Aug 2, 2021
f2ee293
Add tvOS Tests placeholder
jrcrespoh Aug 2, 2021
8e72e40
Fix styling and CI
jrcrespoh Aug 2, 2021
91dcc88
Fix tvOS tests deployment target version
jrcrespoh Aug 2, 2021
63ab70c
Update performance.yml
jrcrespoh Aug 2, 2021
aceb34e
Fix copyright
jrcrespoh Aug 2, 2021
2894146
Incorporate feedback
jrcrespoh Aug 3, 2021
aaaa438
Update tvOS scheme for testing
jrcrespoh Aug 3, 2021
fd9aa8f
Enforce manual build order for iOS
jrcrespoh Aug 3, 2021
c673f77
Deintegrate CocoaPods
jrcrespoh Aug 3, 2021
59b7753
Update performance.yml
jrcrespoh Aug 3, 2021
844401a
Update performance.yml
jrcrespoh Aug 3, 2021
2ca6595
Incorporate feedback
jrcrespoh Aug 4, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add Performance trace
  • Loading branch information
jrcrespoh committed Jul 30, 2021
commit eb6b37bc3e1382e848b319b6186cd3dd76c672dc
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,32 @@ struct ImageView: View {
@ObservedObject var process: Process

var body: some View {
VStack {
if let uiImage = process.image {
Image(uiImage: uiImage).padding(.bottom)
if process.action == .classify {
if process.categories.isEmpty {
Button("Classify Image") {
if #available(iOS 15, tvOS 15, *) {
Task { await process.classifyImageAsync() }
} else {
process.classifyImage()
NavigationView {
VStack {
if let uiImage = process.image {
Image(uiImage: uiImage).padding(.bottom)
if process.action == .classify {
if process.categories.isEmpty {
Button("Classify Image") {
if #available(iOS 15, tvOS 15, *) {
#if swift(>=5.5)
Task { await process.classifyImageAsync() }
#endif
} else {
process.classifyImage()
}
}
} else {
Text("Categories found:")
List(process.categories, id: \.category) { category, confidence in
Text("\(category): \(confidence)")
}
}
} else {
Text("Categories found:")
List(process.categories, id: \.category) { category, confidence in
Text("\(category): \(confidence)")
}
}
} else {
Image(systemName: "questionmark.square").padding(.bottom)
if process.action != .download { Text("No image found!") }
}
} else {
Image(systemName: "questionmark.square").padding(.bottom)
if process.action != .download { Text("No image found!") }
}
}
}
Expand All @@ -57,13 +61,17 @@ struct MainView: View {
"\(action.rawValue) Image",
destination: ImageView(process: process).onAppear {
if #available(iOS 15, tvOS 15, *) {
process.updateActionAsync(to: action)
#if swift(>=5.5)
process.updateActionAsync(to: action)
#endif
} else {
process.updateAction(to: action)
}
if action == .download, process.status == .idle {
if #available(iOS 15, tvOS 15, *) {
Task { await process.downloadImageAsync() }
#if swift(>=5.5)
Task { await process.downloadImageAsync() }
#endif
} else {
process.downloadImage()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,27 @@
//

import SwiftUI
import FirebasePerformance
import Vision

class Process: ObservableObject {
morganchen12 marked this conversation as resolved.
Show resolved Hide resolved
@Published var status: ProcessStatus = .idle
@Published var action: ProcessAction?
@Published var image: UIImage?
var categories: [(category: String, confidence: VNConfidence)] = []
let precision: Float = 0.7
let trace = Performance.sharedInstance().trace(name: "Classification")
jrcrespoh marked this conversation as resolved.
Show resolved Hide resolved
let site = "https://firebase.google.com/downloads/brand-guidelines/PNG/logo-logomark.png"
#if os(tvOS)
let platform = "tvOS"
#elseif os(iOS)
let platform = "iOS"
#endif

init() {
trace?.setValue("\(precision)", forAttribute: "precision")
trace?.setValue(platform, forAttribute: "platform")
}

#if swift(>=5.5)
@MainActor @available(iOS 15, tvOS 15,*) func updateStatusAsync(to newStatus: ProcessStatus) {
Expand All @@ -39,9 +53,7 @@ class Process: ObservableObject {
@available(iOS 15, tvOS 15, *) func downloadImageAsync() async {
await updateStatusAsync(to: .running)

guard let url =
URL(string: "https://www.gstatic.com/devrel-devsite/prod/v854c54f3442b5b06d9" +
"7cb2bf43f3647f489796c80c33899ecd29b91ae5303388/firebase/images/lockup.png")
guard let url = URL(string: site)
else {
jrcrespoh marked this conversation as resolved.
Show resolved Hide resolved
await updateStatusAsync(to: .failure)
print("Failure obtaining URL.")
Expand Down Expand Up @@ -84,7 +96,9 @@ class Process: ObservableObject {
let handler = VNImageRequestHandler(ciImage: ciImage, options: [:])
let request = VNClassifyImageRequest()
await updateStatusAsync(to: .running)
trace?.start()
try? handler.perform([request])
trace?.stop()

guard let observations = request.results else {
print("Failed to obtain classification results.")
Expand All @@ -93,7 +107,7 @@ class Process: ObservableObject {
}

categories = observations
.filter { $0.hasMinimumRecall(0.01, forPrecision: 0.9) }
.filter { $0.hasMinimumRecall(0.01, forPrecision: precision) }
.map { ($0.identifier, $0.confidence) }

await updateStatusAsync(to: .success)
Expand All @@ -116,9 +130,7 @@ class Process: ObservableObject {

func downloadImage() {
updateStatus(to: .running)
guard let url =
URL(string: "https://www.gstatic.com/devrel-devsite/prod/v854c54f3442b5b06d9" +
"7cb2bf43f3647f489796c80c33899ecd29b91ae5303388/firebase/images/lockup.png")
guard let url = URL(string: site)
else {
updateStatus(to: .failure)
print("Failure obtaining URL.")
Expand Down Expand Up @@ -158,7 +170,9 @@ class Process: ObservableObject {
let handler = VNImageRequestHandler(ciImage: ciImage, options: [:])
let request = VNClassifyImageRequest()
updateStatus(to: .running)
trace?.start()
try? handler.perform([request])
trace?.stop()

guard let observations = request.results else {
print("Failed to obtain classification results.")
Expand All @@ -167,7 +181,7 @@ class Process: ObservableObject {
}

categories = observations
.filter { $0.hasMinimumRecall(0.01, forPrecision: 0.9) }
.filter { $0.hasMinimumRecall(0.01, forPrecision: precision) }
.map { ($0.identifier, $0.confidence) }

updateStatus(to: .success)
Expand Down