<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Svrf</title>
    <description>The latest articles on DEV Community by Svrf (@svrf).</description>
    <link>https://dev.to/svrf</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F484%2Fb5483766-9adf-4839-89f7-aeca038e2429.png</url>
      <title>DEV Community: Svrf</title>
      <link>https://dev.to/svrf</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/svrf"/>
    <language>en</language>
    <item>
      <title>A Quick Start Guide for 3D Face Filters using the Svrf SDK</title>
      <dc:creator>Artem Titoulenko</dc:creator>
      <pubDate>Mon, 04 Feb 2019 16:45:06 +0000</pubDate>
      <link>https://dev.to/svrf/a-quick-start-guide-for-3d-face-filters-using-the-svrf-sdk-31j1</link>
      <guid>https://dev.to/svrf/a-quick-start-guide-for-3d-face-filters-using-the-svrf-sdk-31j1</guid>
      <description>&lt;h2&gt;
  
  
  Getting Started iOS
&lt;/h2&gt;

&lt;p&gt;To demonstrate searching for, and using, Svrf Face Filters we will create a basic iOS app that searches for a Face Filter and applies it to your face. For simplicity we will focus exclusively on the iPhone X which allows us to rely on ARKit to handle face detection, face mesh generation, and model morphing. We will cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Installing the SvrfSDK and setting up a Svrf API Key&lt;/li&gt;
&lt;li&gt;  Compose an interface with an ARSCNView, a search bar, and a UICollectionView to hold the search results&lt;/li&gt;
&lt;li&gt;  Create a &lt;code&gt;VirtualContentUpdater&lt;/code&gt; class which implements &lt;code&gt;ARSCNViewDelegate&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Devise a &lt;code&gt;RemoteFaceFilter&lt;/code&gt; class which extends &lt;code&gt;SCNNode&lt;/code&gt; and can load the 3D model of a &lt;code&gt;SvrfMedia&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Plumbing to handle search bar input, showing/hiding the keyboard, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Building the Interface
&lt;/h3&gt;

&lt;p&gt;First, lets create a single-view new Xcode project named FaceFilterDemo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FSelecting-Single-View-Project-1024x707.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FSelecting-Single-View-Project-1024x707.png" alt="Create a Single View App"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FNaming-Project-1024x707.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FNaming-Project-1024x707.png" alt="Name the app FaceFilterDemo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's create a basic layout for our application using Interface Builder. Our application needs an ARSCNView to display the ARKit scene, a text box to input searches, and a Collection View to display the results. Let’s add those components and wire them up:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FWiring-Up-Interface-1024x589.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FWiring-Up-Interface-1024x589.png" alt="Wiring up the basic interface"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make sure that the &lt;code&gt;ViewController&lt;/code&gt; implements the &lt;code&gt;UISearchBarDelegate&lt;/code&gt; protocol, and that the &lt;code&gt;searchBar.delegate&lt;/code&gt; is set to &lt;code&gt;self&lt;/code&gt; on &lt;code&gt;viewDidLoad()&lt;/code&gt;. Set the background of the Search Results View to be "Clear Color", set "Scroll Direction" to Horizontal, and turn on "Bounce Horizontally".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FSearch-Result-Cell-1024x686.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FSearch-Result-Cell-1024x686.png" alt="Setting bounce and flow direction on the search results view"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can then set the "Search Style" of the search bar to "Minimal" to make it translucent and look like it's floating on top of the ARSCNView. We should also give it a more descriptive placeholder to show the purpose of of the search bar. Let’s set it as “Search for Face Filters”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FSearch-Bar-1024x779.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FSearch-Bar-1024x779.png" alt="Setting placeholder and search style on the search bar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing the SvrfSDK Pod
&lt;/h3&gt;

&lt;p&gt;In order to query the Svrf API we need to install the &lt;a href="https://github.com/SVRF/svrf-ios-sdk" rel="noopener noreferrer"&gt;SvrfSDK&lt;/a&gt; from &lt;a href="https://cocoapods.org/" rel="noopener noreferrer"&gt;CocoaPods&lt;/a&gt;. If you don't have CocoaPods installed, you should follow the installation guide on their website, or follow the &lt;a href="https://github.com/SVRF/svrf-ios-sdk" rel="noopener noreferrer"&gt;SvrfSDK&lt;/a&gt; installation instructions to install the SDK directly into your application. In the root of the &lt;code&gt;FaceFilterDemo&lt;/code&gt; folder create a file named &lt;code&gt;Podfile&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Podfile&lt;/span&gt;
&lt;span class="n"&gt;platform&lt;/span&gt; &lt;span class="ss"&gt;:ios&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'12.0'&lt;/span&gt;

&lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="s1"&gt;'FaceFilterDemo'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;use_frameworks!&lt;/span&gt;

  &lt;span class="c1"&gt;# Pods for FaceFilterDemo&lt;/span&gt;
    &lt;span class="n"&gt;pod&lt;/span&gt; &lt;span class="s1"&gt;'SvrfSDK'&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After you have saved the Podfile, close Xcode, open a terminal, navigate to the root of the project directory, and run &lt;code&gt;pod install&lt;/code&gt;. This will install the &lt;code&gt;SvrfSDK&lt;/code&gt; pod and its dependencies. Now instead of opening the Xcode Project, you should open the &lt;code&gt;FaceFilterDemo.xcworkspace&lt;/code&gt; file in the project root directory. You'll know you did it right if you see a "Pods" project alongside the "FaceFilterDemo" project in Xcode.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating and Adding a Svrf API Key
&lt;/h3&gt;

&lt;p&gt;Accessing the API requires an API Key. You can get an API Key by logging into the &lt;a href="https://www.svrf.com/" rel="noopener noreferrer"&gt;Svrf website&lt;/a&gt; and navigating to your &lt;a href="https://www.svrf.com/user/settings" rel="noopener noreferrer"&gt;User Settings&lt;/a&gt;. At the bottom you can name your key and describe what it will be used for.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FFilling-in-Form-For-Key.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FFilling-in-Form-For-Key.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After you sign up, you should be presented with your API Key:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FGetting-Your-Key.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FGetting-Your-Key.png" alt="Don't worry, this key is long gone"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Add a property named &lt;code&gt;SVRF_API_KEY&lt;/code&gt; to the &lt;code&gt;Info.plist&lt;/code&gt; file whose value is your new API Key:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FAdd-Svrf-API-Key.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FAdd-Svrf-API-Key.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Authenticating with the Svrf API
&lt;/h3&gt;

&lt;p&gt;To test that the key works correctly and to authenticate with the API, we import the &lt;code&gt;SvrfSDK&lt;/code&gt; framework and call the &lt;code&gt;SvrfSDK.authenticate&lt;/code&gt; method. A good place to authenticate is when our application starts: in the &lt;code&gt;-application:didFinishLaunchingWithOptions:&lt;/code&gt; method of our &lt;code&gt;AppDelegate&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;// AppDelegate.swift&lt;/span&gt;

&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;UIKit&lt;/span&gt;
&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;SvrfSDK&lt;/span&gt;

&lt;span class="kd"&gt;@UIApplicationMain&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;AppDelegate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UIResponder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;UIApplicationDelegate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;window&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UIWindow&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;

  &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;application&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;application&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UIApplication&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;didFinishLaunchingWithOptions&lt;/span&gt; &lt;span class="nv"&gt;launchOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;UIApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;LaunchOptionsKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]?)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;SvrfSDK&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Successfully authenticated with the Svrf API!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nv"&gt;onFailure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
      &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Could not authenticate with the Svrf API: &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After launching the Simulator, we should see the success text in the logs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Searching for Face Filters
&lt;/h3&gt;

&lt;p&gt;Now that we are authenticated with the service, let's search for some Face Filters! First we should wire up our search bar and the search results view as &lt;code&gt;@IBOutlet&lt;/code&gt;s in our &lt;code&gt;ViewController&lt;/code&gt;. Then we specify that the &lt;code&gt;ViewController&lt;/code&gt; implements the &lt;code&gt;UISearchBarDelegate&lt;/code&gt; protocol, set the &lt;code&gt;searchBar&lt;/code&gt;'s &lt;code&gt;delegate&lt;/code&gt; to &lt;code&gt;self&lt;/code&gt;, and implement &lt;code&gt;searchBarSearchButtonClicked(_:)&lt;/code&gt;. We can then use the SvrfSDK to search for 3D Face Filters by calling the &lt;code&gt;+search(query:options:onSuccess:onFailure)&lt;/code&gt; method of the SvrfSDK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ViewController.swift&lt;/span&gt;

&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;UIKit&lt;/span&gt;
&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;ARKit&lt;/span&gt;
&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;SvrfSDK&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;ViewController&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UIViewController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;@IBOutlet&lt;/span&gt; &lt;span class="k"&gt;weak&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;sceneView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ARSCNView&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="kd"&gt;@IBOutlet&lt;/span&gt; &lt;span class="k"&gt;weak&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;searchBar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UISearchBar&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="kd"&gt;@IBOutlet&lt;/span&gt; &lt;span class="k"&gt;weak&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;searchResultsView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UICollectionView&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;

  &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;viewDidLoad&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;viewDidLoad&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;searchBar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delegate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;extension&lt;/span&gt; &lt;span class="kt"&gt;ViewController&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UISearchBarDelegate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;searchBarSearchButtonClicked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;searchBar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UISearchBar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;guard&lt;/span&gt;   &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;searchBar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Searching for &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;searchOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;SearchOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_3d&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="kt"&gt;SvrfSDK&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;searchOptions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;allMedia&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
      &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"got &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;allMedia&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt; results"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nv"&gt;onFailure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
      &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Could not search for FaceFilters: &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Searching for "Movies" Face Filters should show you how many results were returned for that query, along with the names and canonical URLs for those filters:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FMovies-Search-Result-1024x742.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FMovies-Search-Result-1024x742.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Searching for Movies
Got 7 results
Lego Batman: https://www.svrf.com/vr/Lego-Batman/730872
Iron Man: https://www.svrf.com/vr/Iron-Man/730870
Loki: https://www.svrf.com/vr/Loki/663718
Flash: https://www.svrf.com/vr/Flash/730869
Starlord: https://www.svrf.com/vr/Starlord/720510
Spiderman Mask: https://www.svrf.com/vr/Spiderman-Mask/730873
Black Panther: https://www.svrf.com/vr/Black-Panther/730867
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Other fun Face Filters to search for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Breakfast&lt;/li&gt;
&lt;li&gt;  Animal&lt;/li&gt;
&lt;li&gt;  Meme&lt;/li&gt;
&lt;li&gt;  Cute&lt;/li&gt;
&lt;li&gt;  Comic Book&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the most basic API usage, but there's a lot more that the &lt;a href="https://github.com/SVRF/svrf-ios-sdk" rel="noopener noreferrer"&gt;SvrfSDK&lt;/a&gt; offers. You can fetch &lt;a href="https://github.com/SVRF/svrf-ios-sdk#trending-endpoint" rel="noopener noreferrer"&gt;trending Face Filters&lt;/a&gt;, filter by a certain category, and also search through thousands of 360 photos and videos. You can get a feel for the content that we curate by browsing the &lt;a href="https://www.svrf.com/" rel="noopener noreferrer"&gt;Svrf website&lt;/a&gt;. Read onward to learn how to use these Face Filters in a ARKit Session where you can try on the superhero masks in the search results!&lt;/p&gt;

&lt;h2&gt;
  
  
  Displaying Search Results
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Interface for a Search Result
&lt;/h3&gt;

&lt;p&gt;Now that we know we can search for Face Filters, let's show them to the user in our Collection View and have them try them on. First, we’ll show the user a preview of the Face Filter. Each &lt;code&gt;SvrfMedia&lt;/code&gt; returned by the &lt;code&gt;SvrfSDK.search&lt;/code&gt; method has a collection of rendered images under &lt;code&gt;media.files.images&lt;/code&gt; which we will use to show a preview of the Face Filter. You can see additional properties that &lt;code&gt;Media&lt;/code&gt; have in the &lt;a href="https://developers.svrf.com/docs#operation/getById" rel="noopener noreferrer"&gt;Svrf API docs&lt;/a&gt;. &lt;code&gt;UICollectionView&lt;/code&gt; requires elements which extend &lt;code&gt;UICollectionViewCell&lt;/code&gt;, so we will make a class called &lt;code&gt;SearchCollectionViewCell&lt;/code&gt;. This will manage the preview image view of a &lt;code&gt;SvrfMedia&lt;/code&gt;. Our &lt;code&gt;SearchCollectionViewCell&lt;/code&gt; class will contain a single method called &lt;code&gt;setupWith(media:)&lt;/code&gt;. That method will take a &lt;code&gt;SvrfMedia&lt;/code&gt;, fetch an image from the URL at &lt;code&gt;media.files?.images?._720x720&lt;/code&gt;, and set the fetched image to the image the cell is displaying.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;    &lt;span class="c1"&gt;// SearchCollectionViewCell.swift&lt;/span&gt;

    &lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;UIKit&lt;/span&gt;
    &lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;SvrfSDK&lt;/span&gt;

    &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;SearchCollectionViewCell&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UICollectionViewCell&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;@IBOutlet&lt;/span&gt; &lt;span class="k"&gt;weak&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;imageView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UIImageView&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;

      &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;setupWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;media&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;SvrfMedia&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;imageView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;

        &lt;span class="k"&gt;guard&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;previewImage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;media&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;images&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_720x720&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;imageUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;string&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;previewImage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

          &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Could not fetch 720x720 image"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kt"&gt;URLSession&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;imageUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nv"&gt;completionHandler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Could not fetch image: &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="k"&gt;return&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="kt"&gt;DispatchQueue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;remoteImage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UIImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imageView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;remoteImage&lt;/span&gt;
              &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resume&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the Interface Builder view, drop in an Image View into the search result cell view, ctrl+drag that image view into the &lt;code&gt;SearchCollectionViewCell&lt;/code&gt; class as an &lt;code&gt;@IBOutlet&lt;/code&gt; named &lt;code&gt;imageView&lt;/code&gt;. Additionally specify that the &lt;code&gt;SearchResultCell&lt;/code&gt;'s class is &lt;code&gt;SearchCollectionViewCell&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FSearch-Result-Cell-Identifier-1024x687.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FSearch-Result-Cell-Identifier-1024x687.png" alt="Set the Identifier to "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FSetting-Search-Collection-View-on-Cell-1024x687.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FSetting-Search-Collection-View-on-Cell-1024x687.png" alt="Set the class to SearchCollectionViewCell"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Showing All of the Search Results
&lt;/h3&gt;

&lt;p&gt;In order to show all of the results of our search we need to implement all of the required methods for &lt;code&gt;UICollectionViewDataSource&lt;/code&gt; and &lt;code&gt;UICollectionViewDelegate&lt;/code&gt; in our &lt;code&gt;ViewController&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;    &lt;span class="c1"&gt;// ViewController.swift&lt;/span&gt;

    &lt;span class="kd"&gt;extension&lt;/span&gt; &lt;span class="kt"&gt;ViewController&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UICollectionViewDataSource&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;UICollectionViewDelegate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;collectionView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;collectionView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UICollectionView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numberOfItemsInSection&lt;/span&gt; &lt;span class="nv"&gt;section&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;searchResults&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;collectionView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;collectionView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UICollectionView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cellForItemAt&lt;/span&gt; &lt;span class="nv"&gt;indexPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;IndexPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;UICollectionViewCell&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;guard&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;cell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;searchResultsView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dequeueReusableCell&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;withReuseIdentifier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"SearchResultCell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;for&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;indexPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as?&lt;/span&gt; &lt;span class="kt"&gt;SearchCollectionViewCell&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;UICollectionViewCell&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;cell&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setupWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;media&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;searchResults&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;indexPath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;cell&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;collectionView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;collectionView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UICollectionView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;didSelectItemAt&lt;/span&gt; &lt;span class="nv"&gt;indexPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;IndexPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;media&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;searchResults&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;indexPath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="c1"&gt;// Result selected&lt;/span&gt;
        &lt;span class="c1"&gt;// Do something with the resulting media when it's selected&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now set the &lt;code&gt;searchResultsView&lt;/code&gt;'s &lt;code&gt;delegate&lt;/code&gt; and &lt;code&gt;dataSource&lt;/code&gt; to be &lt;code&gt;self&lt;/code&gt; so that the &lt;code&gt;searchResultsView&lt;/code&gt; knows where to fetch its data from and how to draw the cells representing the data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;    &lt;span class="c1"&gt;// ViewController.swift&lt;/span&gt;

    &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;ViewController&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UIViewController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// ...&lt;/span&gt;

      &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;viewDidLoad&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ...&lt;/span&gt;

        &lt;span class="c1"&gt;// This ViewController will tell the UICollectionView how to render its&lt;/span&gt;
        &lt;span class="c1"&gt;// results, and will also be the data source for the collection view&lt;/span&gt;
        &lt;span class="n"&gt;searchResultsView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delegate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;
        &lt;span class="n"&gt;searchResultsView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dataSource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's fire up the app and search for "Movies". When your search completes you should see several superhero Face Filters. Congrats, you're using the Svrf API!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FMovies-Search-Result-Preview.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FMovies-Search-Result-Preview.png" alt="Try searching for other Face Filters!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Using ARKit and Trying On Face Filters
&lt;/h2&gt;

&lt;p&gt;For the final part of our guide, we will allow the user to select a Face Filter and try it on. This step is more complex as it requires setting up the ARKit session, creating classes to manage the Face Filter's 3D model, interacting with ARSCNView, and applying the blend shapes that ARKit detects to the model being displayed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Allow access to front-camera
&lt;/h3&gt;

&lt;p&gt;First we need to add a &lt;code&gt;NSCameraUsageDescription&lt;/code&gt; key to our &lt;code&gt;Info.plist&lt;/code&gt; whose value will be a description of what our app will use the camera for.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FAdding-Privacy-Notice.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FAdding-Privacy-Notice.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Starting the &lt;code&gt;ARSession&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;When the &lt;code&gt;ViewController&lt;/code&gt; view appears we need to start the &lt;code&gt;sceneView&lt;/code&gt;'s session and tell it that we want to do face tracking with the &lt;a href="https://developer.apple.com/documentation/arkit/arfacetrackingconfiguration" rel="noopener noreferrer"&gt;&lt;code&gt;ARFaceTrackingConfiguration&lt;/code&gt;&lt;/a&gt;. When the view will disappear, we should pause the session so as to reduce CPU usage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;    &lt;span class="c1"&gt;// ViewController.swift&lt;/span&gt;

    &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;ViewController&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UIViewController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// ...&lt;/span&gt;
      &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;viewWillAppear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;animated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;viewWillAppear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;animated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// Run the ARSCNView session&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;configuration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ARFaceTrackingConfiguration&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;sceneView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ARSession&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;RunOptions&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

        &lt;span class="c1"&gt;// Keep the screen on&lt;/span&gt;
        &lt;span class="kt"&gt;UIApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isIdleTimerDisabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;viewWillDisappear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;animated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;viewWillDisappear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;animated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// Pause the ARSCNView session&lt;/span&gt;
        &lt;span class="n"&gt;sceneView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pause&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;// Let the screen sleep&lt;/span&gt;
        &lt;span class="kt"&gt;UIApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isIdleTimerDisabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Representing a Face Filter as a &lt;code&gt;SCNNode&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;In order for our Face Filter to be used in the &lt;code&gt;ARSCNView&lt;/code&gt; session, we need to be able to represent it as an &lt;a href="https://developer.apple.com/documentation/scenekit/scnnode" rel="noopener noreferrer"&gt;&lt;code&gt;SCNNode&lt;/code&gt;&lt;/a&gt;. Our Face Filters come with a variety of 3D model formats, but we always have glTF models. For your convenience the &lt;code&gt;SvrfSDK&lt;/code&gt; includes a method called &lt;code&gt;+getFaceFilter&lt;/code&gt; which will fetch, parse, and convert the glTF model for a Face Filter into a &lt;code&gt;SCNNode&lt;/code&gt; hierarchy. The &lt;code&gt;SCNNodes&lt;/code&gt; also have blendshape data attached if the original glTF model has weights defined for it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;    &lt;span class="c1"&gt;// RemoteFaceFilter.swift&lt;/span&gt;
    &lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Foundation&lt;/span&gt;
    &lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;SceneKit&lt;/span&gt;
    &lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;ARKit&lt;/span&gt;
    &lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;SvrfSDK&lt;/span&gt;

    &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;RemoteFaceFilter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;SCNNode&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Root node which will have the Face Filter as its child&lt;/span&gt;
      &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;faceFilter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;SCNNode&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;

      &lt;span class="c1"&gt;// BlendShapeAnimation&lt;/span&gt;
      &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;blendShapes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;ARFaceAnchor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;BlendShapeLocation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;NSNumber&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[:]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;didSet&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

          &lt;span class="c1"&gt;// Each child node may have blend shape targets so we enumerate over all of them to make sure&lt;/span&gt;
          &lt;span class="c1"&gt;// that each blend target is expressed completely&lt;/span&gt;
          &lt;span class="n"&gt;faceFilter&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enumerateHierarchy&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;morpher&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;targets&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="kt"&gt;SvrfSDK&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setBlendShapes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blendShapes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;blendShapes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;for&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;loadFaceFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;media&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;SvrfMedia&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// Generate a Face Filter SCNNode from a Media in a background thread&lt;/span&gt;
        &lt;span class="kt"&gt;DispatchQueue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;global&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;qos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;background&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;unowned&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
          &lt;span class="kt"&gt;SvrfSDK&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getFaceFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;media&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;faceFilter&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
            &lt;span class="c1"&gt;// Remove any existing Face Filter from the SCNScene&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resetFaceFilter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="c1"&gt;// Set new Face Filter&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;faceFilter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;faceFilter&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nv"&gt;onFailure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;. &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;})&lt;/span&gt;

          &lt;span class="c1"&gt;// Add the Face Filter as a child node&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;head&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;faceFilter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addChildNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="c1"&gt;// Deletes all childNodes from the self.faceFilter&lt;/span&gt;
      &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;resetFaceFilter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;head&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;faceFilter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;child&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;childNodes&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeFromParentNode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Giving the &lt;code&gt;ARSCNView&lt;/code&gt; a Delegate
&lt;/h3&gt;

&lt;p&gt;Our preferred approach to managing multiple Face Filters is to create a &lt;code&gt;VirtualContentUpdater&lt;/code&gt; class which will manage a virtual face node (which represents your face). The &lt;code&gt;VirtualContentUpdater&lt;/code&gt; will also implement &lt;code&gt;ARSCNViewDelegate&lt;/code&gt; and pass changes to the &lt;a href="https://developer.apple.com/documentation/arkit/arfaceanchor" rel="noopener noreferrer"&gt;ARFaceAnchor&lt;/a&gt; (a class defining a virtual mesh of your face) to the virtual face node. This way we can offload the resource management to another class (&lt;code&gt;RemoteFaceFilter&lt;/code&gt;) which will be responsible for fetching and loading the 3D model data from a &lt;code&gt;SvrfMedia&lt;/code&gt;. It's worth carefully reading the documentation for &lt;a href="https://developer.apple.com/documentation/arkit/arfaceanchor" rel="noopener noreferrer"&gt;ARFaceAnchor&lt;/a&gt; as it gives a great overview of what kind of data it can give you and how you should use it. The following &lt;code&gt;VirtualContentUpdater&lt;/code&gt; contains its own root node (&lt;code&gt;faceNode&lt;/code&gt;), and a &lt;code&gt;RemoteFaceFilter&lt;/code&gt; whose blend shapes it updates when the user moves their face.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;    &lt;span class="c1"&gt;// VirtualContentUpdater.swift&lt;/span&gt;

    &lt;span class="c1"&gt;// An `ARSCNViewDelegate` which adds and updates the virtual face content in response to the ARFaceTracking session.&lt;/span&gt;
    &lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;SceneKit&lt;/span&gt;
    &lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;ARKit&lt;/span&gt;

    &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;VirtualContentUpdater&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;NSObject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// The virtual content that should be displayed and updated.&lt;/span&gt;
        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;remoteFaceFilter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;RemoteFaceFilter&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;didSet&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nf"&gt;setupFaceNodeContent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// A reference to the node that was added by ARKit in `renderer(_:didAdd:for:)`.&lt;/span&gt;
        &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;faceNode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;SCNNode&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;

        &lt;span class="c1"&gt;// The queue reference&lt;/span&gt;
        &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;serialQueue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;DispatchQueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"com.example.FaceFilterDemo.serialSceneKitQueue"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;//MARK: private functions&lt;/span&gt;
        &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;setupFaceNodeContent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;guard&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;faceNode&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="nf"&gt;resetFaceNode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;remoteFaceFilter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addChildNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;resetFaceNode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;guard&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;faceNode&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="c1"&gt;// Remove all childNodes from the faceNode&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;child&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;childNodes&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeFromParentNode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Extension that realises ARSCNViewDelegate protocol's functions&lt;/span&gt;
    &lt;span class="kd"&gt;extension&lt;/span&gt; &lt;span class="kt"&gt;VirtualContentUpdater&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ARSCNViewDelegate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// ARNodeTracking&lt;/span&gt;
        &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;SCNSceneRenderer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;didAdd&lt;/span&gt; &lt;span class="nv"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;SCNNode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nv"&gt;anchor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ARAnchor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

            &lt;span class="c1"&gt;// Hold onto the `faceNode` so that the session does not need to be restarted when switching Face Filters.&lt;/span&gt;
            &lt;span class="n"&gt;faceNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;

            &lt;span class="c1"&gt;// Setup face node content in async thread&lt;/span&gt;
            &lt;span class="n"&gt;serialQueue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setupFaceNodeContent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// ARFaceGeometryUpdate&lt;/span&gt;
        &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;SCNSceneRenderer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;didUpdate&lt;/span&gt; &lt;span class="nv"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;SCNNode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nv"&gt;anchor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ARAnchor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

            &lt;span class="c1"&gt;// FaceAnchor unwrapping&lt;/span&gt;
            &lt;span class="k"&gt;guard&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;faceAnchor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;anchor&lt;/span&gt; &lt;span class="k"&gt;as?&lt;/span&gt; &lt;span class="kt"&gt;ARFaceAnchor&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="c1"&gt;// Update virtualFaceNode's blendshapes with FaceAnchor's blendshapes&lt;/span&gt;
            &lt;span class="n"&gt;remoteFaceFilter&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blendShapes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;faceAnchor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blendShapes&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Finishing Touches
&lt;/h3&gt;

&lt;p&gt;The last step in the process is to wire up all of the new behavior into our &lt;code&gt;ViewController&lt;/code&gt; so that a user can actually try on the superhero masks they were searching for. We will create a new &lt;code&gt;VirtualContentUpdater&lt;/code&gt; called &lt;code&gt;contentUpdater&lt;/code&gt;, a new &lt;code&gt;RemoteFaceFilter&lt;/code&gt;, assign the &lt;code&gt;sceneView&lt;/code&gt;'s &lt;code&gt;delegate&lt;/code&gt; to &lt;code&gt;contentUpdater&lt;/code&gt;, and make &lt;code&gt;contentUpdater&lt;/code&gt; keep track of &lt;code&gt;remoteFaceFilter&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;    &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;ViewController&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UIViewController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;@IBOutlet&lt;/span&gt; &lt;span class="k"&gt;weak&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;sceneView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ARSCNView&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
      &lt;span class="kd"&gt;@IBOutlet&lt;/span&gt; &lt;span class="k"&gt;weak&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;searchBar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UISearchBar&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
      &lt;span class="kd"&gt;@IBOutlet&lt;/span&gt; &lt;span class="k"&gt;weak&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;searchResultsView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UICollectionView&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;

      &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;searchResults&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;SvrfMedia&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
      &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;contentUpdater&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;VirtualContentUpdater&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;remoteFaceFilter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;RemoteFaceFilter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

      &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;viewDidLoad&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;viewDidLoad&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;// ContentUpdater will tell the ARSCNView what to draw&lt;/span&gt;
        &lt;span class="n"&gt;sceneView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delegate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;contentUpdater&lt;/span&gt;

        &lt;span class="c1"&gt;// ContentUpdater's virtual face node will dictate what Face Filter to render&lt;/span&gt;
        &lt;span class="n"&gt;contentUpdater&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;remoteFaceFilter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;remoteFaceFilter&lt;/span&gt;

        &lt;span class="c1"&gt;// This ViewController will handle the behavior of the searchBar&lt;/span&gt;
        &lt;span class="n"&gt;searchBar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delegate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;

        &lt;span class="c1"&gt;// This ViewController will tell the UICollectionView how to render its results, and will also be the&lt;/span&gt;
        &lt;span class="c1"&gt;// data source for the collection view&lt;/span&gt;
        &lt;span class="n"&gt;searchResultsView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delegate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;
        &lt;span class="n"&gt;searchResultsView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dataSource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;So&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="n"&gt;we&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;tell&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="nv"&gt;remoteFaceFilter&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;load&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;Face&lt;/span&gt; &lt;span class="kt"&gt;Filter&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;tapped&lt;/span&gt; &lt;span class="n"&gt;search&lt;/span&gt; &lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="c1"&gt;// ViewController.swift&lt;/span&gt;

    &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="kd"&gt;extension&lt;/span&gt; &lt;span class="kt"&gt;ViewController&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UICollectionViewDataSource&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;UICollectionViewDelegate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// ...&lt;/span&gt;
      &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;collectionView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;collectionView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UICollectionView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;didSelectItemAt&lt;/span&gt; &lt;span class="nv"&gt;indexPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;IndexPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;media&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;searchResults&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;indexPath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="c1"&gt;// Result selected, load a new Face Filter&lt;/span&gt;
        &lt;span class="n"&gt;remoteFaceFilter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loadFaceFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;media&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;media&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;And&lt;/span&gt; &lt;span class="n"&gt;finally&lt;/span&gt; &lt;span class="n"&gt;lets&lt;/span&gt; &lt;span class="n"&gt;clean&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt; &lt;span class="n"&gt;called&lt;/span&gt; &lt;span class="n"&gt;by&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;search&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt; &lt;span class="n"&gt;when&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="n"&gt;searches&lt;/span&gt; &lt;span class="n"&gt;or&lt;/span&gt; &lt;span class="n"&gt;taps&lt;/span&gt; &lt;span class="s"&gt;"cancel"&lt;/span&gt; &lt;span class="n"&gt;so&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt; &lt;span class="n"&gt;they&lt;/span&gt; &lt;span class="n"&gt;close&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;keyboard&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="kd"&gt;extension&lt;/span&gt; &lt;span class="kt"&gt;ViewController&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UISearchBarDelegate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;searchBarCancelButtonClicked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;searchBar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UISearchBar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Hide searchCollectionView&lt;/span&gt;
            &lt;span class="n"&gt;searchResultsView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isHidden&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

            &lt;span class="c1"&gt;// Reset text in searchBar&lt;/span&gt;
            &lt;span class="n"&gt;searchBar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;

            &lt;span class="c1"&gt;// Hide cancel button in searchBar&lt;/span&gt;
            &lt;span class="n"&gt;searchBar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;showsCancelButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

            &lt;span class="c1"&gt;// Hide keyboard&lt;/span&gt;
            &lt;span class="n"&gt;searchBar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resignFirstResponder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;searchBarSearchButtonClicked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;searchBar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UISearchBar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Hide keyboard&lt;/span&gt;
            &lt;span class="n"&gt;searchBar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resignFirstResponder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

            &lt;span class="c1"&gt;// Show the searchResultsView&lt;/span&gt;
            &lt;span class="n"&gt;searchResultsView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isHidden&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

            &lt;span class="k"&gt;guard&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;searchBar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Searching for &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;searchOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;SearchOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_3d&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

            &lt;span class="kt"&gt;SvrfSDK&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;searchOptions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;allMedia&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
                &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Got &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;allMedia&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt; results"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;searchResults&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;allMedia&lt;/span&gt;
                &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;searchResultsView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reloadData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nv"&gt;onFailure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
                &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Could not search for FaceFilters: &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's try on those superhero Face Filters!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FIMG_2465-473x1024.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.svrf.com%2Fwp-content%2Fuploads%2F2019%2F01%2FIMG_2465-473x1024.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Going Further
&lt;/h2&gt;

&lt;p&gt;We have scratched the surface of what you can create with the Svrf API and the Svrf SDK for iOS. Head over to the &lt;a href="https://developers.svrf.com" rel="noopener noreferrer"&gt;Svrf Developers Site&lt;/a&gt; to explore API clients in a variety of languages and to see what other content you can discover through the Svrf API. To see a more complete Demo app with error handling, loading spinners, and reset buttons check out &lt;a href="https://github.com/SVRF/svrf-api/tree/master/examples/ARKitFaceFilterDemo" rel="noopener noreferrer"&gt;https://github.com/SVRF/svrf-api/tree/master/examples/ARKitFaceFilterDemo&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Learn more at &lt;a href="https://developers.svrf.com" rel="noopener noreferrer"&gt;https://developers.svrf.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/SVRF/svrf-ios-sdk" rel="noopener noreferrer"&gt;Svrf iOS SDK&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/SVRF/svrf-api/tree/master/examples" rel="noopener noreferrer"&gt;Other Svrf API examples&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.svrf.com/" rel="noopener noreferrer"&gt;Svrf Website&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/SVRF/SvrfGLTFSceneKit" rel="noopener noreferrer"&gt;SvrfGLTFSceneKit&lt;/a&gt;, our glTF loader&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://blog.svrf.com/svrf-api-quick-start-guide-for-3d-face-filters/" rel="noopener noreferrer"&gt;blog.svrf.com&lt;/a&gt; by Artem Titoulenko on January 17, 2019.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>showdev</category>
      <category>ios</category>
      <category>swift</category>
    </item>
  </channel>
</rss>
