Swift Examples - Replicate

Our replicate swift client will automatically switch from Replicate's synchronous API to the polling API after sixty seconds. If you are making predictions that take longer than sixty seconds, you will see multiple requests in the 'Request History' tab for a single prediction.

Service setup

Create a Replicate service in the AIProxy dashboard

Follow the integration guide, selecting the Replicate icon on the 'Create a New Service' form.

How to generate a Flux-Schnell image by Black Forest Labs, using Replicate

import AIProxy

/* Uncomment for BYOK use cases */
// let replicateService = AIProxy.replicateDirectService(
//     unprotectedAPIKey: "your-replicate-key"
// )

/* Uncomment for all other production use cases */
// let replicateService = AIProxy.replicateService(
//     partialKey: "partial-key-from-your-developer-dashboard",
//     serviceURL: "service-url-from-your-developer-dashboard"
// )


do {
    let input = ReplicateFluxSchnellInputSchema(
        prompt: "Monument valley, Utah"
    )
    let urls = try await replicateService.createFluxSchnellImages(
        input: input,
        secondsToWait: 30
    )
    print("Done creating Flux-Schnell images: ", urls)
} catch AIProxyError.unsuccessfulRequest(let statusCode, let responseBody) {
    print("Received \(statusCode) status code with response body: \(responseBody)")
} catch {
    // You may want to catch additional Foundation errors and pop the appropriate UI
    // to the user. See "How to catch Foundation errors for specific conditions" here:
    // https://www.aiproxy.com/docs/integration-options.html
    print("Could not create Flux-Schnell image: \(error.localizedDescription)")
}

See the full range of controls for generating an image by viewing ReplicateFluxSchnellInputSchema.swift

How to generate a Flux-Dev image by Black Forest Labs, using Replicate

import AIProxy

/* Uncomment for BYOK use cases */
// let replicateService = AIProxy.replicateDirectService(
//     unprotectedAPIKey: "your-replicate-key"
// )

/* Uncomment for all other production use cases */
// let replicateService = AIProxy.replicateService(
//     partialKey: "partial-key-from-your-developer-dashboard",
//     serviceURL: "service-url-from-your-developer-dashboard"
// )

do {
    let input = ReplicateFluxDevInputSchema(
        prompt: "Monument valley, Utah. High res",
        goFast: false
    )
    let urls = try await replicateService.createFluxDevImages(
        input: input,
        secondsToWait: 30
    )
    print("Done creating Flux-Dev images: ", urls)
} catch AIProxyError.unsuccessfulRequest(let statusCode, let responseBody) {
    print("Received non-200 status code: \(statusCode) with response body: \(responseBody)")
} catch {
    // You may want to catch additional Foundation errors and pop the appropriate UI
    // to the user. See "How to catch Foundation errors for specific conditions" here:
    // https://www.aiproxy.com/docs/integration-options.html
    print("Could not create Flux-Dev image: \(error.localizedDescription)")
}

See the full range of controls for generating an image by viewing ReplicateFluxDevInputSchema.swift

How to generate a Flux-Pro image by Black Forest Labs, using Replicate

This snippet generates a version 1.1 image. If you would like to generate version 1, make the following substitutions:

  • ReplicateFluxProInputSchema_v1_1 -> ReplicateFluxProInputSchema
  • createFluxProImage_v1_1 -> createFluxProImage
import AIProxy

/* Uncomment for BYOK use cases */
// let replicateService = AIProxy.replicateDirectService(
//     unprotectedAPIKey: "your-replicate-key"
// )

/* Uncomment for all other production use cases */
// let replicateService = AIProxy.replicateService(
//     partialKey: "partial-key-from-your-developer-dashboard",
//     serviceURL: "service-url-from-your-developer-dashboard"
// )

do {
    let input = ReplicateFluxProInputSchema_v1_1(
        prompt: "Monument valley, Utah. High res"
        promptUpsampling: true
    )
    let url = try await replicateService.createFluxProImage_v1_1(
        input: input,
        secondsToWait: 60
    )
    print("Done creating Flux-Pro 1.1 image: ", url)
} catch AIProxyError.unsuccessfulRequest(let statusCode, let responseBody) {
    print("Received \(statusCode) status code with response body: \(responseBody)")
} catch {
    // You may want to catch additional Foundation errors and pop the appropriate UI
    // to the user. See "How to catch Foundation errors for specific conditions" here:
    // https://www.aiproxy.com/docs/integration-options.html
    print("Could not create Flux-Pro 1.1 image: \(error.localizedDescription)")
}

See the full range of controls for generating an image by viewing ReplicateFluxProInputSchema_v1_1.swift

How to generate a Flux-PuLID image using Replicate

On macOS, use NSImage(named:) in place of UIImage(named:)

import AIProxy

/* Uncomment for BYOK use cases */
// let replicateService = AIProxy.replicateDirectService(
//     unprotectedAPIKey: "your-replicate-key"
// )

/* Uncomment for all other production use cases */
// let replicateService = AIProxy.replicateService(
//     partialKey: "partial-key-from-your-developer-dashboard",
//     serviceURL: "service-url-from-your-developer-dashboard"
// )

guard let image = NSImage(named: "face") else {
    print("Could not find an image named 'face' in your app assets")
    return
}

guard let imageURL = AIProxy.encodeImageAsURL(
    image: image,
    compressionQuality: 0.8
) else {
    print("Could not convert image to a local data URI")
    return
}

do {
    let input = ReplicateFluxPulidInputSchema(
        mainFaceImage: imageURL,
        prompt: "smiling man holding sign with glowing green text 'PuLID for FLUX'",
        numOutputs: 1,
        startStep: 4
    )
    let urls = try await replicateService.createFluxPuLIDImages(
        input: input,
        secondsToWait: 60
    )
    print("Done creating Flux-PuLID image: ", urls)
} catch AIProxyError.unsuccessfulRequest(let statusCode, let responseBody) {
    print("Received non-200 status code: \(statusCode) with response body: \(responseBody)")
} catch {
    // You may want to catch additional Foundation errors and pop the appropriate UI
    // to the user. See "How to catch Foundation errors for specific conditions" here:
    // https://www.aiproxy.com/docs/integration-options.html
    print("Could not create Flux-Pulid images: \(error.localizedDescription)")
}

How to generate an image from a reference image using Flux ControlNet on Replicate

There are many controls to play with for this use case. Please see ReplicateFluxDevControlNetInputSchema.swift for the full range of controls.

import AIProxy

/* Uncomment for BYOK use cases */
// let replicateService = AIProxy.replicateDirectService(
//     unprotectedAPIKey: "your-replicate-key"
// )

/* Uncomment for all other production use cases */
// let replicateService = AIProxy.replicateService(
//     partialKey: "partial-key-from-your-developer-dashboard",
//     serviceURL: "service-url-from-your-developer-dashboard"
// )

do {
    let input = ReplicateFluxDevControlNetInputSchema(
        controlImage: URL(string: "https://example.com/your/image")!,
        prompt: "a cyberpunk with natural greys and whites and browns",
        controlStrength: 0.4
    )
    let output = try await replicateService.createFluxDevControlNetImages(
        input: input,
        secondsToWait: 60
    )
    print("Done creating Flux-ControlNet image: ", output)
} catch AIProxyError.unsuccessfulRequest(let statusCode, let responseBody) {
    print("Received non-200 status code: \(statusCode) with response body: \(responseBody)")
} catch {
    // You may want to catch additional Foundation errors and pop the appropriate UI
    // to the user. See "How to catch Foundation errors for specific conditions" here:
    // https://www.aiproxy.com/docs/integration-options.html
    print("Could not create Flux-ControlNet image: \(error.localizedDescription)")
}

How to generate an SDXL image image by Stability AI, using Replicate

import AIProxy

/* Uncomment for BYOK use cases */
// let replicateService = AIProxy.replicateDirectService(
//     unprotectedAPIKey: "your-replicate-key"
// )

/* Uncomment for all other production use cases */
// let replicateService = AIProxy.replicateService(
//     partialKey: "partial-key-from-your-developer-dashboard",
//     serviceURL: "service-url-from-your-developer-dashboard"
// )

do {
    let input = ReplicateSDXLInputSchema(
        prompt: "Monument valley, Utah"
    )
    let urls = try await replicateService.createSDXLImages(
        input: input,
        secondsToWait: 2
    )
    print("Done creating SDXL images: ", urls)
} catch AIProxyError.unsuccessfulRequest(let statusCode, let responseBody) {
    print("Received non-200 status code: \(statusCode) with response body: \(responseBody)")
} catch {
    // You may want to catch additional Foundation errors and pop the appropriate UI
    // to the user. See "How to catch Foundation errors for specific conditions" here:
    // https://www.aiproxy.com/docs/integration-options.html
    print("Could not create SDXL image: \(error.localizedDescription)")
}

See the full range of controls for generating an image by viewing ReplicateSDXLInputSchema.swift

How to generate an SDXL Fresh Ink image by fofr, using Replicate

import AIProxy

/* Uncomment for BYOK use cases */
// let replicateService = AIProxy.replicateDirectService(
//     unprotectedAPIKey: "your-replicate-key"
// )

/* Uncomment for all other production use cases */
// let replicateService = AIProxy.replicateService(
//     partialKey: "partial-key-from-your-developer-dashboard",
//     serviceURL: "service-url-from-your-developer-dashboard"
// )

do {
    let input = ReplicateSDXLFreshInkInputSchema(
        prompt: "A fresh ink TOK tattoo of monument valley, Utah",
        negativePrompt: "ugly, broken, distorted"
    )
    let urls = try await replicateService.createSDXLFreshInkImages(
        input: input,
        secondsToWait: 60
    )
    print("Done creating SDXL Fresh Ink images: ", urls)
} catch AIProxyError.unsuccessfulRequest(let statusCode, let responseBody) {
    print("Received non-200 status code: \(statusCode) with response body: \(responseBody)")
} catch {
    // You may want to catch additional Foundation errors and pop the appropriate UI
    // to the user. See "How to catch Foundation errors for specific conditions" here:
    // https://www.aiproxy.com/docs/integration-options.html
    print("Could not create SDXL Fresh Ink images: \(error.localizedDescription)")
}

See the full range of controls for generating an image by viewing ReplicateSDXLFreshInkInputSchema.swift

How to call your own models on Replicate

Look in the ReplicateService+Convenience.swift file for inspiration on how to do this.

  1. Generate the Encodable representation of your input schema. Take a look at any of the input schemas used in ReplicateService+Convenience.swift for inspiration. Find the schema format that you should conform to using replicate's web dashboard and tapping through Your Model > API > Schema > Input Schema
  2. Generate the Decodable representation of your output schema. The output schema is defined on replicate's site at Your Model > API > Schema > Output Schema. I find that unfortunately these schemas are not always accurate, so sometimes you have to look at the network response manually. For simple cases, a typealias will do (for example, if the output schema is just a string or an array of strings). Look at ReplicateFluxOutputSchema.swift for inspiration. If you need help doing this, please reach out.
  3. Call replicateService.runOfficialModel or replicateService.runCommunityModel. Community models have a version while official models do not.
  4. Call replicateService.getPredictionOutput on the result from step 3.

You'll need to change YourInputSchema, YourOutputSchema and your-model-version in this snippet:

import AIProxy

/* Uncomment for BYOK use cases */
// let replicateService = AIProxy.replicateDirectService(
//     unprotectedAPIKey: "your-replicate-key"
// )

/* Uncomment for all other production use cases */
// let replicateService = AIProxy.replicateService(
//     partialKey: "partial-key-from-your-developer-dashboard",
//     serviceURL: "service-url-from-your-developer-dashboard"
// )

do {
    let input = YourInputSchema(
        prompt: "Monument valley, Utah"
    )
    let prediction: ReplicatePrediction = try await replicateService.runCommunityModel( /* or runOfficialModel */
        version: "your-model-version",
        input: input,
        secondsToWait: secondsToWait
    )
    let output: YourOutputSchema = try await replicateService.getPredictionOutput(prediction)

    // Do something with output

} catch AIProxyError.unsuccessfulRequest(let statusCode, let responseBody) {
    print("Received \(statusCode) status code with response body: \(responseBody)")
} catch {
    // You may want to catch additional Foundation errors and pop the appropriate UI
    // to the user. See "How to catch Foundation errors for specific conditions" here:
    // https://www.aiproxy.com/docs/integration-options.html
    print("Could not run replicate model: \(error.localizedDescription)")
}

How to upload a file to Replicate's CDN

import AIProxy

/* Uncomment for BYOK use cases */
// let replicateService = AIProxy.replicateDirectService(
//     unprotectedAPIKey: "your-replicate-key"
// )

/* Uncomment for all other production use cases */
// let replicateService = AIProxy.replicateService(
//     partialKey: "partial-key-from-your-developer-dashboard",
//     serviceURL: "service-url-from-your-developer-dashboard"
// )

guard let image = NSImage(named: "face") else {
    print("Drop face.jpeg into Assets first")
    return
}

guard let imageData = AIProxy.encodeImageAsJpeg(image: image, compressionQuality: 0.5) else {
    print("Could not encode the image as jpeg")
    return
}

do {
    let fileUploadResponse = try await replicateService.uploadFile(
        contents: imageData,
        contentType: "image/jpeg",
        name: "face.jpg"
    )
    print("""
            Image uploaded. Find it at \(fileUploadResponse.urls.get)
            You can use this file until \(fileUploadResponse.expiresAt ?? "")
            """)

} catch AIProxyError.unsuccessfulRequest(let statusCode, let responseBody) {
    print("Received non-200 status code: \(statusCode) with response body: \(responseBody)")
} catch {
    // You may want to catch additional Foundation errors and pop the appropriate UI
    // to the user. See "How to catch Foundation errors for specific conditions" here:
    // https://www.aiproxy.com/docs/integration-options.html
    print("Could not upload file to replicate: \(error.localizedDescription)")
}

How to create a replicate model for your own Flux fine tune

Replace <your-account>:

import AIProxy

/* Uncomment for BYOK use cases */
// let replicateService = AIProxy.replicateDirectService(
//     unprotectedAPIKey: "your-replicate-key"
// )

/* Uncomment for all other production use cases */
// let replicateService = AIProxy.replicateService(
//     partialKey: "partial-key-from-your-developer-dashboard",
//     serviceURL: "service-url-from-your-developer-dashboard"
// )

do {
    let modelURL = try await replicateService.createModel(
        owner: "<your-account>",
        name: "my-model",
        description: "My great model",
        hardware: "gpu-t4",
        visibility: .private
    )
    print("Your model is at \(modelURL)")
}  catch AIProxyError.unsuccessfulRequest(let statusCode, let responseBody) {
    print("Received \(statusCode) status code with response body: \(responseBody)")
} catch {
    print("Could not create replicate model: \(error.localizedDescription)")
}

How to upload training data for your own Flux fine tune

Create a zip file called training.zip and drop it in your Xcode assets. See the "Prepare your training data" section of this guide for tips on what to include in the zip file. Then run:

import AIProxy

/* Uncomment for BYOK use cases */
// let replicateService = AIProxy.replicateDirectService(
//     unprotectedAPIKey: "your-replicate-key"
// )

/* Uncomment for all other production use cases */
// let replicateService = AIProxy.replicateService(
//     partialKey: "partial-key-from-your-developer-dashboard",
//     serviceURL: "service-url-from-your-developer-dashboard"
// )

guard let trainingData = NSDataAsset(name: "training") else {
    print("""
            Drop training.zip file into Assets first.
            See the 'Prepare your training data' of this guide:
            https://replicate.com/blog/fine-tune-flux
            """)
    return
}

do {
    let fileUploadResponse = try await replicateService.uploadTrainingZipFile(
        zipData: trainingData.data,
        name: "training.zip"
    )
    print("""
            Training file uploaded. Find it at \(fileUploadResponse.urls.get)
            You you can train with this file until \(fileUploadResponse.expiresAt ?? "")
            """)

}  catch AIProxyError.unsuccessfulRequest(let statusCode, let responseBody) {
    print("Received \(statusCode) status code with response body: \(responseBody)")
} catch {
    print("Could not upload file to replicate: \(error.localizedDescription)")
}

How to train a flux fine-tune

Use the <training-url> returned from the snippet above. Use the <model-name> that you used from the snippet above that.

import AIProxy

/* Uncomment for BYOK use cases */
// let replicateService = AIProxy.replicateDirectService(
//     unprotectedAPIKey: "your-replicate-key"
// )

/* Uncomment for all other production use cases */
// let replicateService = AIProxy.replicateService(
//     partialKey: "partial-key-from-your-developer-dashboard",
//     serviceURL: "service-url-from-your-developer-dashboard"
// )

do {
    // You should experiment with the settings in `ReplicateFluxTrainingInput.swift` to
    // find what works best for your use case.
    //
    // The `layersToOptimizeRegex` argument here speeds training and works well for faces.
    // You could could optionally remove that argument to see if the final trained model
    // works better for your user case.
    let trainingInput = ReplicateFluxTrainingInput(
        inputImages: URL(string: "<training-url>")!,
        layersToOptimizeRegex: "transformer.single_transformer_blocks.(7|12|16|20).proj_out",
        steps: 200,
        triggerWord: "face"
    )
    let reqBody = ReplicateTrainingRequestBody(destination: "<model-owner>/<model-name>", input: trainingInput)


    // Find valid version numbers here: https://replicate.com/ostris/flux-dev-lora-trainer/train
    let training = try await replicateService.createTraining(
        modelOwner: "ostris",
        modelName: "flux-dev-lora-trainer",
        versionID: "d995297071a44dcb72244e6c19462111649ec86a9646c32df56daa7f14801944",
        body: reqBody
    )
    print("Get training status at: \(training.urls?.get?.absoluteString ?? "unknown")")
}  catch AIProxyError.unsuccessfulRequest(let statusCode, let responseBody) {
    print("Received \(statusCode) status code with response body: \(responseBody)")
} catch {
    print("Could not create replicate training: \(error.localizedDescription)")
}

How to poll the flux fine-tune for training complete

Use the <url> that is returned from the snippet above.

import AIProxy

/* Uncomment for BYOK use cases */
// let replicateService = AIProxy.replicateDirectService(
//     unprotectedAPIKey: "your-replicate-key"
// )

/* Uncomment for all other production use cases */
// let replicateService = AIProxy.replicateService(
//     partialKey: "partial-key-from-your-developer-dashboard",
//     serviceURL: "service-url-from-your-developer-dashboard"
// )

// This URL comes from the output of the sample above
let url = URL(string: "<url>")!

do {
    let training = try await replicateService.pollForTrainingComplete(
        url: url,
        pollAttempts: 100,
        secondsBetweenPollAttempts: 10
    )
    print("""
          Flux training status: \(training.status?.rawValue ?? "unknown")
          Your model version is: \(training.output?.version ?? "unknown")
          """)
}  catch AIProxyError.unsuccessfulRequest(let statusCode, let responseBody) {
    print("Received \(statusCode) status code with response body: \(responseBody)")
} catch {
    print("Could not poll for the replicate training: \(error.localizedDescription)")
}

How to generate images with your own flux fine-tune

Use the <version> string that was returned from the snippet above, but do not include the model owner and model name in the string.

import AIProxy

/* Uncomment for BYOK use cases */
// let replicateService = AIProxy.replicateDirectService(
//     unprotectedAPIKey: "your-replicate-key"
// )

/* Uncomment for all other production use cases */
// let replicateService = AIProxy.replicateService(
//     partialKey: "partial-key-from-your-developer-dashboard",
//     serviceURL: "service-url-from-your-developer-dashboard"
// )

let input = ReplicateFluxFineTuneInputSchema(
    prompt: "an oil painting of my face on a blimp",
    model: .dev,
    numInferenceSteps: 28  // Replicate recommends around 28 steps for `.dev` and 4 for `.schnell`
)

do {
    let predictionResponse = try await replicateService.createPrediction(
        version: "<version>",
        input: input,
        output: ReplicatePredictionResponseBody<[URL]>.self
    )

    let predictionOutput: [URL] = try await replicateService.pollForPredictionOutput(
        predictionResponse: predictionResponse,
        pollAttempts: 30,
        secondsBetweenPollAttempts: 5
    )
    print("Done creating predictionOutput: \(predictionOutput)")
}  catch AIProxyError.unsuccessfulRequest(let statusCode, let responseBody) {
    print("Received \(statusCode) status code with response body: \(responseBody)")
} catch {
    print("Could not create replicate prediction: \(error.localizedDescription)")
}