Snapchat-like filters, AR lenses, and real-time facial animations.

Overview

react-native-deepar

npm version CircleCI Commitizen friendly license

Snapchat-like filters, AR lenses, and real-time facial animations.

React-Native wrapper for DeepAR.

Table of Contents

What is DeepAR?

Preview
Preview Image
This GIF taken from DeepAR offical site.

DeepAR is an infrastructure where you can make AR applications in ease. DeepAR is not free, but you can create applications that can be used by up to 10 people for testing purposes for free.

  • In order to use DeepAR, you need to generate an API key. You can generate the API key from the Developer Panel.
  • With the Asset Store, you can buy ready to use AR content. If you're looking for free filters, here is some: Free Filter Pack
  • With the DeepAR Studio, you can create, edit and fine tune your own AR content. To learn DeepAR Studio, visit DeepAR Help Center.

You can visit DeepAR's offical site to learn more.

Getting Started

⚠️ This library under development, if you found a bug, please open an issue from here.

⚠️ It only works on physical devices, not will work with simulator.

npm install react-native-deepar

Note: Don't forget install Pods for iOS and rebuild your app.

Compatibility

DeepAR SDK lib version Required React Native Version
3.4.2 react-native-deepar >= 0.1.0 unknown

Installing AR Models

  1. Put your AR models into a desired destination
  2. Create react-native.config.js like below:
module.exports = {
  assets: ['./assets/effects'], // <-- example destination
};
  1. Add a NPM script like below:
{
  "scripts": {
+   "asset": "./node_modules/.bin/react-native-deepar-link"
  }
}
  1. Run the script to link your AR models
npm run asset

Note: If you remove an AR model, you can run the same command for unlinking removed asset.

Using AR Models over Internet

  1. Install rn-fetch-blob to your project
  2. You can use AR models over internet like below:
import RNFetchBlob from 'rn-fetch-blob';

RNFetchBlob.config({
  fileCache: true,
})
  .fetch('GET', 'http://betacoins.magix.net/public/deepar-filters/8bitHearts')
  .then((res) => {
    deepARRef?.current?.switchEffectWithPath({
      path: res.path(),
      slot: 'effect',
    });
  });

Usage

Make registration to DeepAR and get an API key from Developer Panel.

{ // .. }} /> ); };">
import React, {useRef} from 'react';
import DeepAR, {IDeepARHandle} from 'react-native-deepar';

const App = () => {
  const deepARRef = useRef<IDeepARHandle>(null);

  return (
    <DeepAR
      ref={deepARRef}
      apiKey="your-api-key"
      style={{flex: 1}}
      onInitialized={() => {
        // ..
      }}
    />
  );
};

API

The component can take a number of inputs to customize it as needed. They are outlined below:

Props

Prop Type Default Required Description
apiKey String null true Make registration to DeepAR and get an API key from Developer Panel.

Events

These are various events that you can hook into and fire functions on in the component:

Callback Description
onInitialized Called when the DeepAR is initialized. DeepAR methods should not be called before the initialization is completed.
onEffectSwitched Called when an effect has been switched.
onScreenshotTaken Called when the screen capture is finished.
onVideoRecordingPrepared Called when the video recording is prepared.
onVideoRecordingStarted The start of the video recording process is not synchronous, so this method will be called when the video recording is started.
onVideoRecordingFinished Called when the video recording is finished.
onCameraSwitched Fired when camera switched.
onFaceVisibilityChanged Called when the user's face becomes visible or invisible.
onImageVisibilityChanged Called when a natural image is being tracked and the visibility has changed.
onError Called when an error occur, like the model path not found or the effect file failed to load.

Methods

These are the various methods.

General

Method Description
switchEffect The method used to switch any effect in the scene. Effects are places in slots. Every slot is identified by its unique name and can hold one effect at any given moment. Every subsequent call to this method removes the effect that was previously displayed in this slot.
switchEffectWithPath Same as switchEffect but with path.
fireTrigger This method allows the user to fire a custom animation trigger for model animations from code. To fire a custom trigger, the trigger string must match the custom trigger set in the Studio when creating the effect.
takeScreenshot Captures a screenshot of the current screen. When a screenshot is done onScreenshotTaken will be called with a resulting screenshot.

Camera Control

Method Description
switchCamera Switches the camera, back and front.
setFlashOn Toggle flash.

Video Recording

Method Description
startRecording Starts video recording of the camera preview.
pauseRecording Pauses video recording.
resumeRecording Resumes video recording after it has been paused with pauseRecording.
finishRecording Stops video recording and starts the process of saving the recorded video to the file system. When the file is saved, the method onVideoRecordingFinished will be called.
setAudioMute Mutes/unmutes the audio while video recording.

Change Parameters

For more details about changeParameter API read our article here.

Method Description
changeParameterFloat This method allows the user to change the value of blendshape parameters during runtime.
changeParameterVec4 This method is used to change the certain color of a Game Object at runtime.
changeParameterVec3 This method is used to change the transform of a Game Object at runtime, so here you can change the object position, rotation or scale.
changeParameterBool Let say you want to put a button in your app that enables or disables Game Object at runtime. (let's say you want your filter character to put their glasses on or take them off) This function helps you to enable/disable the value.
changeParameterString Change a string parameter on a game object. The most common use for this override is to change blend mode and culling mode properties of a game object. Note: Only available in iOS
changeParameterTexture This method allows the user to load an image and set it as a texture during runtime. This can be useful if you want to leverage our background segmentation feature, and change the background in your filter.

Core

Method Description
pause Pauses the rendering. This method will not release any resources and should be used only for temporary pause (e.g. user goes to the next screen).
resume Resumes the rendering if it was previously paused, otherwise doesn't do anything.
setLiveMode This is an optimization method and it allows the user to indicate the DeepAR in which mode it should operate. If called with true value, DeepAR will expect a continuous flow of new frames and it will optimize its inner processes for such workload. An example of this is the typical use case of processing the frames from the camera stream. If called with false it will optimize for preserving resources and memory by pausing the rendering after each processed frame. A typical use case for this is when the user needs to process just one image.
setFaceDetectionSensitivity This method allows the user to change face detection sensitivity. The sensitivity parameter can range from 0 to 3, where 0 is the fastest but might not recognize smaller (further away) faces, and 3 is the slowest but will find smaller faces. By default, this parameter is set to 1.
showStats Display debugging stats on screen.

Background Segmentation

DeepAR has Background Segmentation feature, with this feature you can change your background in real-time.

Background Segmentation

There is a filter called Background from Free Filter Pack and you can use this filter.

How change background image?

Switch the Background effect and apply new background image like below:

import {TextureSourceTypes} from 'react-native-deepar';
import RNFetchBlob from 'rn-fetch-blob';

RNFetchBlob.config({})
  .fetch('GET', 'https://random.imagecdn.app/450/800')
  .then((res) => {
    deepARRef?.current?.changeParameterTexture({
      gameObject: 'Background',
      component: 'MeshRenderer',
      parameter: 's_texColor',
      type: TextureSourceTypes.BASE64,
      value: res.base64(),
    });
  });

Example App

# clone the project
git clone https://github.com/ridvanaltun/react-native-deepar.git

# go into the project
cd react-native-deepar

# make project ready
npm run bootstrap

# go into the example
cd example

# copy environment file and set your api keys (bundle id is com.example.reactnativedeepar)
cp .env.example .env

# run for android
npm run android

# or

# run for ios
npm run ios

Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Comments
  • [Android] - Can't start recording a video

    [Android] - Can't start recording a video

    Hi all, just tried this beautiful library, but seems that it won't start recording.

    I was trying 0.10.2 and just updated with 0.10.3 but it still won't start recording.

    This is the error:

    onError => Video recording resolution is 720 x 1460 type => 1

    onError => Could not record video! Stack trace: [libcore.io.IoBridge.open(IoBridge.java:574), java.io.RandomAccessFile.<init>(RandomAccessFile.java:289), java.io.RandomAccessFile.<init>(RandomAccessFile.java:152), android.media.MediaMuxer.<init>(MediaMuxer.java:357), ai.deepar.ar.MediaMuxerWrapper.<init>(MediaMuxerWrapper.java:60), ai.deepar.ar.DeepAR.startVideoRecording(DeepAR.java:1489), com.reactnativedeepar.RNTDeepAR.startRecording(RNTDeepAR.java:334), com.reactnativedeepar.RNTDeepARViewManager.receiveCommand(RNTDeepARViewManager.java:189), com.reactnativedeepar.RNTDeepARViewManager.receiveCommand(RNTDeepARViewManager.java:24), com.facebook.react.uimanager.NativeViewHierarchyManager.dispatchCommand(NativeViewHierarchyManager.java:832), com.facebook.react.uimanager.UIViewOperationQueue$DispatchCommandOperation.executeWithExceptions(UIViewOperationQueue.java:323), com.facebook.react.uimanager.UIViewOperationQueue$1.run(UIViewOperationQueue.java:879), com.facebook.react.uimanager.UIViewOperationQueue.flushPendingBatches(UIViewOperationQueue.java:1025), com.facebook.react.uimanager.UIViewOperationQueue.access$2600(UIViewOperationQueue.java:47), com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded(UIViewOperationQueue.java:1085), com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.java:29), com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:175), com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame(ChoreographerCompat.java:85), android.view.Choreographer$CallbackRecord.run(Choreographer.java:1140), android.view.Choreographer.doCallbacks(Choreographer.java:946), android.view.Choreographer.doFrame(Choreographer.java:870), android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1127), android.os.Handler.handleCallback(Handler.java:938), android.os.Handler.dispatchMessage(Handler.java:99), android.os.Looper.loopOnce(Looper.java:210), android.os.Looper.loop(Looper.java:299), android.app.ActivityThread.main(ActivityThread.java:8105), java.lang.reflect.Method.invoke(Native Method), com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:556), com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1045)] type => 3

    bug 
    opened by adembacajmemmo 9
  • Android build failed -

    Android build failed - "Execution failed for task ':react-native-deepar:bundleReleaseLocalLintAar'."

    -Execution failed for task ':react-native-deepar:bundleReleaseLocalLintAar'. -Error while evaluating property 'hasLocalAarDeps' of task ':react-native-deepar:bundleReleaseLocalLintAar'

    -Direct local .aar file dependencies are not supported when building an AAR. The resulting AAR would be broken because the classes and Android resources from any local .aar file dependencies would not be packaged in the resulting AAR. Previous versions of the Android Gradle Plugin produce broken AARs in this case too (despite not throwing this error). The following direct local .aar file dependencies of the :react-native-deepar project caused this error: {projectDir}\node_modules\react-native-deepar\android\libs\deepar-3.4.4.aar

    react-native : 0.68.2. react-native-deepar : ^0.10.5

    opened by Dhruv2110 5
  • Face/Body masking not being cut out for background segmentation

    Face/Body masking not being cut out for background segmentation

    Hi I'm interested in using this for an enterprise project, but I need to ensure the project works correctly on React Native first. Specifically, the background removal feature during video recording.

    I've managed to startup the example app (there's some outdated dependency issues there, I'll push a PR with those updated). The face tracking is working, and the backgrounds show up. But the face is not being cut out of the background, and instead the background is completely overlaying the camera view. Am I missing something here? Any help would be appreciated to figure out what's going on.

    Extra info:

    • I'm using a Galaxy A32. This meets the minimum requirements stated here: https://docs.deepar.ai/deepar-sdk/deep-ar-sdk-for-android/getting-started
    • The backgrounds being used are currently the default images, but I'd like to be able to change the backgrounds to a video as well once this initial problem is solved
    opened by MaxwellDG 4
  • Unable to record video

    Unable to record video

    I am getting this error while trying to start recording video

    Could not record video! 
    Stack trace: [libcore.io.IoBridge.open(IoBridge.java:492), java.io.RandomAccessFile.<init>(RandomAccessFile.java:289), java.io.RandomAccessFile.<init>(RandomAccessFile.java:152), android.media.MediaMuxer.<init>(MediaMuxer.java:356), ai.deepar.ar.MediaMuxerWrapper.<init>(MediaMuxerWrapper.java:59), ai.deepar.ar.DeepAR.startVideoRecording(DeepAR.java:1291), ai.deepar.ar.DeepAR.startVideoRecording(DeepAR.java:1215), com.reactnativedeepar.RNTDeepAR.startRecording(RNTDeepAR.java:301), com.reactnativedeepar.RNTDeepARViewManager.receiveCommand(RNTDeepARViewManager.java:199), com.reactnativedeepar.RNTDeepARViewManager.receiveCommand(RNTDeepARViewManager.java:27), com.facebook.react.uimanager.NativeViewHierarchyManager.dispatchCommand(NativeViewHierarchyManager.java:831), com.facebook.react.uimanager.UIViewOperationQueue$DispatchCommandOperation.executeWithExceptions(UIViewOperationQueue.java:323), com.facebook.react.uimanager.UIViewOperationQueue$1.run(UIViewOperationQueue.java:879), com.facebook.react.uimanager.UIViewOperationQueue.flushPendingBatches(UIViewOperationQueue.java:1026), com.facebook.react.uimanager.UIViewOperationQueue.access$2600(UIViewOperationQueue.java:47), com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded(UIViewOperationQueue.java:1086), com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.java:29), com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:175), com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame(ChoreographerCompat.java:85), android.view.Choreographer$CallbackRecord.run(Choreographer.java:1159), android.view.Choreographer.doCallbacks(Choreographer.java:983), android.view.Choreographer.doFrame(Choreographer.java:904), android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1146), android.os.Handler.handleCallback(Handler.java:938), android.os.Handler.dispatchMessage(Handler.java:99), android.os.Looper.loop(Looper.java:263), android.app.ActivityThread.main(ActivityThread.java:8292), java.lang.reflect.Method.invoke(Native Method), com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:612), com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1006)]
    

    I am using the latest version of this package, React Native version: 0.69.0

    bug android 
    opened by MadCoderNS 3
  •  Error: Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref

    Error: Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref

    I just followed steps mentioned in Readme file but cant move forward from here

    return ( <SafeAreaView style={styles.container}> Camera Homescreen <DeepAR ref={deepARRef} apiKey="0c0bf879c6b93878a416410b57eebf11b2b8e43*********************60b3eb716*********" style={{ flex: 1 }} onInitialized={() => { // .. }} />

        </SafeAreaView>
    );
    
    I am not able to get deepar view work ,whenever i add this to return funtion of react native component always throw error like function components cannot have string refs
    
    opened by geniushkg 2
  • Update Readme: Compatibility

    Update Readme: Compatibility

    I don't know this library supports Expo or not or which React-Native versions works without problem, I need to test and learn then update the Compatibility section in README file.

    documentation question 
    opened by ridvanaltun 2
  • Installing AR Models

    Installing AR Models

    Hi @ridvanaltun ! I've tried the example app and it works great, thank you. Now I want to use react-native-deepar in my App, but I have some problems. My react-native.config.js looks like this: example Assets is used for custom fonts and I don't understand how to add AR models.

    Can you explain me what to do in such case?

    question 
    opened by YevZl 1
  • Weird layer showing only on Android

    Weird layer showing only on Android

    I have same implementation and mask for both Android and iOS. But on Android after taking screenshot that weird shadow layer below glasses show up only on Android.

    On iOS works fine. Any idea why and possible fix?

    weird_layer_showing

    opened by andresteves 0
  • Update/dependencies and manifest

    Update/dependencies and manifest

    The last 2 commits are definitely necessary. The first one is optional and I suggest you test it out first. This is clearly a big change since it's actually on the package.json of the main repo (not the example project). And I wasn't able to test everything to see if it broke elsewhere. Regardless, it was necessary to get the example app running.

    I don't think any README changes are required with these. If you do, let me know specifically and I'll add that in.

    opened by MaxwellDG 0
  • OpenGL ES RGBA scaling shader creation unsuccessful

    OpenGL ES RGBA scaling shader creation unsuccessful

    Hi!

    The library was working fine till day before yesterday. Suddenly, from yesterday, no more face related mask or effect works. However filters and effects where face detection and processing is not needed, works perfectly.

    At the same time, I am getting this error message right when deepar is initialized.

    OpenGL ES RGBA scaling shader creation unsuccessful

    I am using the latest version, 10.5

    opened by MadCoderme 0
  • Android build failed- cant generate Release APK

    Android build failed- cant generate Release APK

    Task :react-native-deepar:bundleDebugAar FAILED FAILURE: Build failed with an exception.

    What went wrong: Execution failed for task ‘:react-native-deepar:bundleDebugAar’. Error while evaluating property ‘hasLocalAarDeps’ of task ‘:react-native-deepar:bundleDebugAar’ Direct local .aar file dependencies are not supported when building an AAR.

    This happens when trying to build APK running on Debug mode / connected device works fine but cant generate build.

    ************************** To Overcome ******************************** packagingOptions { pickFirst ‘lib/arm64-v8a/libnative-lib.so’ pickFirst ‘lib/arm64-v8a/libtensorflowlite_c.so’ pickFirst ‘lib/arm64-v8a/libtensorflowlite_gpu_delegate.so’ pickFirst ‘lib/arm64-v8a/libxzimgSDK.so’ pickFirst ‘lib/armeabi-v7a/libnative-lib.so’ pickFirst ‘lib/armeabi-v7a/libtensorflowlite_c.so’ pickFirst ‘lib/armeabi-v7a/libtensorflowlite_gpu_delegate.so’ pickFirst ‘lib/armeabi-v7a/libxzimgSDK.so’ pickFirst ‘lib/x86/libnative-lib.so’ pickFirst ‘lib/x86/libtensorflowlite_c.so’ pickFirst ‘lib/x86/libtensorflowlite_gpu_delegate.so’ pickFirst ‘lib/x86/libxzimgSDK.so’ pickFirst ‘lib/x86_64/libnative-lib.so’ pickFirst ‘lib/x86_64/libtensorflowlite_c.so’ pickFirst ‘lib/x86_64/libtensorflowlite_gpu_delegate.so’ pickFirst ‘lib/x86_64/libxzimgSDK.so’ }

    Now the problem is it comes to full circle - If I do pickFirst then Error while evaluating property ‘hasLocalAarDeps’

    If I dont do Pick first then previous issue also get 2 files found with same lib native issue occurs https://stackoverflow.com/questions/70890854/2-files-found-with-path-lib-arm64-v8a-libc-shared-so-from-inputs-react-na for tensorflowlite gpudelegate etc

    Gradle version 7.3.3 Android Gradle plugin 7.1.1

    bug 
    opened by geniushkg 2
Releases(v0.10.5)
Owner
Rıdvan Altun
Passionate about building high-quality software. JS ninja. :cd:
Rıdvan Altun
A Swift library to take the power of UIView.animateWithDuration(_:, animations:...) to a whole new level - layers, springs, chain-able animations and mixing view and layer animations together!

ver 2.0 NB! Breaking changes in 2.0 - due to a lot of requests EasyAnimation does NOT automatically install itself when imported. You need to enable i

Marin Todorov 3k Dec 27, 2022
A collaborative Augmented Reality iOS experience using Real-time Messaging

Collaborative AR Experience This project creates an augmented reality experience where you can build a scene together with anyone around the world, se

Agora.io Community 9 Dec 1, 2022
A collection of animations for iOS. Simple, just add water animations.

DCAnimationKit A collection of animations for iOS Simply, just add water! DCAnimationKit is a category on UIView to make animations easy to perform. E

Dalton 797 Sep 23, 2022
(Animate CSS) animations for iOS. An easy to use library of iOS animations. As easy to use as an easy thing.

wobbly See Wobbly in action (examples) Add a drop of honey ?? to your project wobbly has a bunch of cool, fun, and easy to use iOS animations for you

Sagaya Abdulhafeez 150 Dec 23, 2021
(Animate CSS) animations for iOS. An easy to use library of iOS animations. As easy to use as an easy thing.

wobbly See Wobbly in action (examples) Add a drop of honey ?? to your project wobbly has a bunch of cool, fun, and easy to use iOS animations for you

Sagaya Abdulhafeez 150 Dec 23, 2021
Easy to read and write chainable animations in Objective-C and Swift

Whats new in version 3.x? Swiftier syntax Swift 4 support Bug fixes and improvements Whats new in version 2.x? Re-architected from the ground up, no m

Jeff Hurray 3.2k Dec 30, 2022
⛓ Easy to Read and Write Multi-chain Animations Lib in Objective-C and Swift.

中文介绍 This project is inspired by JHChainableAnimations! Why Choose LSAnimator & CoreAnimator? You can write complex and easy-to-maintain animations in

木子 1.6k Nov 22, 2022
Physics-based animations for iOS, tvOS, and macOS.

Advance An animation library for iOS, tvOS, and macOS that uses physics-based animations (including springs) to power interactions that move and respo

Tim Donnelly 4.5k Dec 29, 2022
A library of custom iOS View Controller Animations and Interactions.

RZTransitions is a library to help make iOS7 custom View Controller transitions slick and simple. Installation CocoaPods (Recommended) Add the followi

Rightpoint 1.9k Nov 20, 2022
Match animations in SwiftUI and UIKit/AppKit

MatchedAnimation Match animations in SwiftUI and UIKit/AppKit. /// Draw a box in

Ryan Carver 6 Dec 21, 2022
Tools for SwiftUI that helps perform Path and Shape animations, such us morphing circle or shape transformations

SwiftUI+PathAnimations ?? Introduction This packages contains SimilarShape and InterpolatedShape, both can be used to achieve shapes animations with S

Alfredo Delli Bovi 180 Dec 29, 2022
Easily pause and resume SwiftUI animations

swiftui-pausable-animation Easily pause and resume SwiftUI animations! Installation This component is distributed as a Swift package. Just add this re

Gordan Glavaš 6 Nov 24, 2022
Simple UIButton subclass with additional state change animations (e.g. backgroundColor) and missing features

SimpleButton UIButton subclass with animated, state-aware attributes. Easy to subclass and configure! Full API docs Usage Just create your own SimpleB

Andreas Tinoco Lobo 169 Sep 14, 2022
This repo contains swift collection of gui, games, menu, animations, music, payment, etc... for iOS, macOS, watchOS and tvOS

Swift-Collections About: This repo contains a collection of projects built using swift and objective-c Contains projects for macOS iOS iPad watchOS tv

Krisna Pranav 6 Nov 15, 2022
Ease is an event driven animation system that combines the observer pattern with custom spring animations as observers

Ease is an event driven animation system that combines the observer pattern with custom spring animations as observers. It's magic. Features Animate a

Robert-Hein Hooijmans 1.3k Nov 17, 2022
Advanced Natural Motion Animations, Simple Blocks Based Syntax

FlightAnimator Moved to Swift 3.1 Support: For Swift 3.1 - Use tag Version 0.9.9 See Installation Instructions for clarification Introduction FlightAn

Anton 589 Dec 29, 2022
Swift interpolation for gesture-driven animations

Interpolate Interpolate is a powerful Swift interpolation framework for creating interactive gesture-driven animations. Usage The ?? idea of Interpola

Roy Marmelstein 1.8k Dec 20, 2022
An iOS library to natively render After Effects vector animations

Lottie for iOS, macOS (and Android and React Native) View documentation, FAQ, help, examples, and more at airbnb.io/lottie Lottie is a mobile library

Airbnb 23.6k Dec 31, 2022
A library to simplify iOS animations in Swift.

Updated for Swift 4.2 Requires Xcode 10 and Swift 4.2. Installation Drop in the Spring folder to your Xcode project (make sure to enable "Copy items i

Meng To 14k Jan 3, 2023