-
Notifications
You must be signed in to change notification settings - Fork 52
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
chore: replay screenshot #142
Changes from 9 commits
30b39da
b1330b0
cc02437
df0b945
f36129e
34a27b8
973a658
59c31fa
7490ae4
c0f90ba
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -96,6 +96,8 @@ | |
windowViews.setObject(snapshotStatus, forKey: view) | ||
} | ||
|
||
// TODO: IncrementalSnapshot, type=2 | ||
|
||
var wireframes: [Any] = [] | ||
wireframes.append(wireframe.toDict()) | ||
let initialOffset = ["top": 0, "left": 0] | ||
|
@@ -141,6 +143,15 @@ | |
wireframe.height = Int(view.frame.size.height) | ||
let style = RRStyle() | ||
|
||
// no parent id means its the root | ||
if parentId == nil, config.sessionReplayConfig.screenshot { | ||
if let image = view.toImage() { | ||
wireframe.base64 = imageToBase64(image) | ||
} | ||
wireframe.type = "screenshot" | ||
return wireframe | ||
} | ||
|
||
if let textView = view as? UITextView { | ||
wireframe.type = "text" | ||
let isSensitive = config.sessionReplayConfig.maskAllTextInputs || textView.isNoCapture() || textView.isSensitiveText() | ||
|
@@ -190,8 +201,9 @@ | |
if let image = view as? UIImageView { | ||
wireframe.type = "image" | ||
if !image.isNoCapture(), !config.sessionReplayConfig.maskAllImages { | ||
// TODO: check png quality | ||
wireframe.base64 = image.image?.pngData()?.base64EncodedString() | ||
if let image = image.image { | ||
wireframe.base64 = imageToBase64(image) | ||
} | ||
} | ||
} | ||
|
||
|
@@ -274,6 +286,9 @@ | |
} | ||
|
||
@objc private func snapshot() { | ||
// TODO: add debouncer with debouncerDelayMs to take into account how long it takes to execute the | ||
// snapshot method | ||
Comment on lines
+289
to
+290
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since you cannot offload this from the main thread, a debouncer mechanism would be handy, can be separated to PR to get this out of the door since the timer calls |
||
|
||
if !PostHogSDK.shared.isSessionReplayActive() { | ||
return | ||
} | ||
|
@@ -289,17 +304,31 @@ | |
|
||
var screenName: String? | ||
if let controller = window.rootViewController { | ||
if controller is AnyObjectUIHostingViewController { | ||
hedgeLog("SwiftUI snapshot not supported.") | ||
// SwiftUI only supported with screenshot | ||
if controller is AnyObjectUIHostingViewController, !config.sessionReplayConfig.screenshot { | ||
hedgeLog("SwiftUI snapshot not supported, enable screenshot mode.") | ||
return | ||
// screen name only makes sense if we are not using SwiftUI | ||
} else if !config.sessionReplayConfig.screenshot { | ||
screenName = UIViewController.getViewControllerName(controller) | ||
} | ||
screenName = UIViewController.getViewControllerName(controller) | ||
} | ||
|
||
// this cannot run off of the main thread because most properties require to be called within the main thread | ||
// this method has to be fast and do as little as possible | ||
generateSnapshot(window, screenName) | ||
} | ||
|
||
private func imageToBase64(_ image: UIImage) -> String? { | ||
let jpegData = image.jpegData(compressionQuality: 0.3) | ||
let base64 = jpegData?.base64EncodedString() | ||
|
||
if let base64 = base64 { | ||
return "data:image/jpeg;base64,\(base64)" | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
private protocol AnyObjectUIHostingViewController: AnyObject {} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,18 +20,18 @@ class Api: ObservableObject { | |
var logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "main") | ||
|
||
func listBeers(completion _: @escaping ([PostHogBeerInfo]) -> Void) { | ||
guard let url = URL(string: "https://api.punkapi.com/v2/beers") else { | ||
return | ||
} | ||
|
||
logger.info("Requesting beers list...") | ||
URLSession.shared.dataTask(with: url) { _, _, _ in | ||
// guard let url = URL(string: "https://api.punkapi.com/v2/beers") else { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this API does not exist anymore, the sample has to be changed |
||
// return | ||
// } | ||
// | ||
// logger.info("Requesting beers list...") | ||
// URLSession.shared.dataTask(with: url) { _, _, _ in | ||
// let beers = try! JSONDecoder().decode([PostHogBeerInfo].self, from: data!) | ||
// | ||
// DispatchQueue.main.async { | ||
// completion(beers) | ||
// } | ||
}.resume() | ||
// }.resume() | ||
} | ||
|
||
func failingRequest() -> URLSessionDataTask? { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably not needed if we make the
screenshot
the default option since it is always a single image anyway, unless at some point we try to optimize the data transfer by breaking a full image in tiles and only sending the ones that have changed.