join us on Discord for support, updates, and all things Snap AR! See you there!
How To Prefetch Lenses
Hey guys, we would like to know the best way to prefetch lenses before the camera screen is opened.
Our current problem: it takes 3-7 sec for lenses to load so it is hurting the user experience. Users have to wait on the camera screen with the loading animation and nothing happening.
What API can we use to make this happen? What documentation can help us? We tried reading through everything that's available but haven't been able to find a solution. Please help. Thank you.
Best Answer
-
Thank you for posting this question in the forum @Hangoo!
Our API does let you listen for which lenses have been updated and then prefetch them. For future reference, here are the steps to do that on both platforms, starting with iOS.
iOS
To listen for changes to lenses that have been updated, conform the class that manages your camera and lens stack to LensRepositoryGroupObserver. An example implementation is provided in the sample app,
CameraController.repository(_:didUpdateLenses:forGroupID:)
open func repository(_ repository: LensRepository, didUpdateLenses lenses: [Lens], forGroupID groupID: String) { // prefetch lens content (don't prefetch bundled since content is local already) if !groupID.contains(SCCameraKitLensRepositoryBundledGroup) { // the object returned here can be used to cancel the ongoing prefetch operation if need be _ = cameraKit.lenses.prefetcher.prefetch(lenses: lenses, completion: nil) for lens in lenses { cameraKit.lenses.prefetcher.addStatusObserver(self, lens: lens) } } DispatchQueue.main.async { [weak self] in guard let self = self else { return } let lenses = self.groupIDs.flatMap { self.cameraKit.lenses.repository.lenses(groupID: $0) } self.uiDelegate?.cameraController(self, updatedLenses: lenses) } }
You may also want the UI to reflect the fact that a lens is being prefetched, for example, by showing an activity indicator. This can be done by conforming the camera controller to
SCCameraKitLensPrefetcherObserver
. SeeCameraController.prefetcher(_:didUpdate:status:)
for an example implementation.Android
The same thing can be achieved on Android. Here is a code block that demonstrates how the
Prefetcher
exposed from theLensesComponent
can be used to prefetch lenses// content of select list of lenses on demand. var lensesPrefetch = Closeable {} Closeable { lensesPrefetch.close() }.addTo(closeOnDestroy) rootLayout.findViewById<Button> (R.id.lenses_prefetch_button).setOnClickListener { session.lenses.repository.observe(Available(*lensGroups)) {available -> available.whenHasSome { lenses -> // Cancel any running prefetch operation before submitting new one lensesPrefetch.close() // Prefetch available lenses content async lensesPrefetch = session.lenses.prefetcher.run(lenses) { success -> Log.d(TAG, "Finished prefetch of [${lenses.size}] lenses with success: $success") } } }.addTo(closeOnDestroy) }
If you are using
CameraActivity
then you can use this:CameraActivity.Configuration.WithLenses( lensGroupIds = LENS_GROUP_IDS, prefetchLensByIdPattern = "\\S+" )
Please let us know if you have any follow up questions!
1
Answers
-
I'm afraid the 3-7 seconds delay this user experiences is related to camerakit initialization time that I posted on https://community.snap.com/snapar/discussion/1166/objective-c#latest and not related to fetching lenses...
1