WrapFast Documentation

Get Started

In-App Purchases

Firebase

WishKit

AI Backend

Xcode Project

API Client

Support

WrapFast includes a simple Node.js backend to make requests to OpenAI’s and Anthropic’s API.

The purpose of this is prevent storing the API keys within the mobile app and making the requests from there. It’s a pretty bad practice because anyone can easily sniff your HTTP requests and extract the key, for example using the utility proxy Charles.

To avoid this, and save thousand of dollars for you being hacked, WrapFast hides the HTTP request behind a custom backend.

<aside> 💡 If you do not want to deploy a backend, as another option WrapFast supports AI Proxy to make requests securely to OpenAI without exposing your API key. You will find implementations of ChatGPT, Vision and DALL-E in each service class.

Feel free to create an account and check their documentation here: aiproxy.pro Integration Guide: https://www.aiproxy.pro/docs/integration-guide.html Docs: https://github.com/lzell/AIProxySwift?tab=readme-ov-file#how-to-update-the-package

</aside>

The backend implements 4 endpoints that are called from the iOS boilerplate:

Let's take a closer look at them later, but first let's learn how to set up and deploy our backend.

Install Node.js

First of all you need to have installed Node.js and NPM in your Mac.

The minimum required Node version is 21.2.0

To install it just open a Terminal and paste this commands:

brew install node

<aside> ⚠️ If you don’t have Homebrew installed, paste this on your Terminal: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

</aside>

Type node -v to check that Node is correctly installed.

Configuring Environment Variables

You can find the variables that the WrapFast backend uses in the .env.example file.

Remove the trailing .example and open it and replace the values with the proper ones:

<aside> ⚠️ Take into account that the .env file is ignored by Git, because it is included in the .gitgnore file.

</aside>

node secret_generator.js

It generates a new secret key every time you execute it. Generate two and paste it in AUTH_SECRET_KEY and HMAC_SECRET_KEY

You will learn below how the Authentication Flow works. For now just replace the variables 🙂

Authentication Flow

HMAC is a way to make sure messages sent between two places online stay secret and unchanged.

It's like sealing a letter in an envelope with a special wax seal, where the seal is made using a secret recipe.

Only the sender and the receiver know the recipe, so if the seal is intact when the receiver gets the letter, they can be sure it hasn't been opened or changed along the way.

In the WrapFast backend, we use HMAC to add this kind of security to messages or data we send and receive in our apps.

We use two keys that you have to generate with this included script secret_generator.js

Open a Terminal and type to generate a secret key:

node secret_generator.js

Set the two keys generated as AUTH_SECRET_KEY and HMAC_SECRET_KEY

You have to set the AUTH_SECRET_KEY also in the Xcode Project, within Constant.swift file:

enum Api {
        // Auth key generated with the script 'secret_generator.js'
        // It also needs to be configured in the backend side
        static let authKey = "YOUR_GENERATED_AUTH_KEY"
}

In order to authenticate to the backend from the WrapFast iOS app:

"X-Signature": "\\(CryptoUtils.shared.createHmac(key: Const.Api.authKey, phrase: "/" + path))"
var header: [String : String]? {
        switch self {
        case .auth:
            return [
                "X-Signature": "\\(CryptoUtils.shared.createHmac(key: Const.Api.authKey, phrase: "/" + path))"
            ]
            
            // To make requests to our backend endpoints, we fetch the auth secret key stored in the keychain and send it
            // within a X-Signature header.
            // We also send our app identifier to allow handle custom login within the backend depending on which app
            // make the request.
        case .vision, .chatgpt, .dalle:
            let keychain = KeychainSwift()
            let signature = CryptoUtils.shared.createHmac(key: keychain.get(Const.Keychain.tokenKey) ?? "", phrase: "/" + path)
            return [
                "X-Signature": "\\(signature)",
                "X-App-Identifier": "\\(Const.Api.appIdentifier)"
            ]
        }
    }

<aside> ⚠️ In order to be able to make requests to GPT endpoints, you need to have fetched the HMAC_SECRET_KEY from /auth endpoint at least once from your app, and store it securely in the Keychain.

For instance, in the WrapFast boilerplate we do it within the init() of VisionVM, which is the first View that appears once the user has signed in:

**await** fetchBackendAuthIfNecessary()

</aside>

Deploy in Local Environment

Once you have the Environment Variables properly set, you can deploy the backend locally in your Mac. Thus, you can develop your app and use the backend in debug. To do so:

cd wrapfast-backend
npm install
node wrapfast_backend.js

Your server will start running on http://localhost:10000/

Run WrapFast iOS app in a Simulator and try the built-in integration with DALL·E, Vision and ChatGPT

The server’s URL that the iOS app uses is set in the Constants.swif file, in the Api.baseURL parameter.

<aside> ⚠️ It is important that the URL you set as baseURL ends with a Slash /

</aside>

In DEBUG it is set to local host and in production you should set your production URL.

<aside> 💡 If you want to use the local backend with a real device instead of the Simulator, use as baseURL the proper local IP. For instance: http://192.168.1.44:10000/ To know what’s your IP type in a Terminal: ipconfig getifaddr en0

</aside>

You will learn in the next section how to deploy your backend in a hosting service.

Deploy with a hosting service

When your app is live in the App Store or TestFlight, you may need to publish your backend to allow be accessed publicly by your apps.

As indie developers, the most common approach is using a service to host it like Render, Heroku, Netlify, etc.—if you don’t have your own infrastructure.

In this section we are going to explain how to deploy your web service using Render.

Render offers a quite generous free tier to host web services for free. It is very suitable for light MVPs that doesn’t require too much work load, as our case is.

<aside> ⚠️ Take into account that the free instances will spin down after 10 minutes of inactivity, which can delay new requests by 50 seconds or more. To offer a better experience to your users I recommend upgrading to the first paid tier which is just $5 monthly.

</aside>

To deploy your backend you need to push the backend to a GitHub or GitLab repository. Render will detect every new commit you push, deploying new changes automatically.

Once you have the backend in GitHub or Gitlab, follow these steps: