Getting started

Add the Canva Button to an iOS app with the iOS SDK.

Canva provides an SDK to adding the Canva Button to iOS apps. You can use this SDK to launch the Canva editor from within your app.

Here's how it works:

Your app can open the Canva editor in a browser window. The user then creates or edits a design. When the user clicks the Publish button, your app downloads the user's design as an image file.

This tutorial series explains how to add the Canva Button to an empty iOS app. Once you understand the workflow, adapt the steps to add the Canva Button to your existing app

This tutorial assumes you have an API key to use the Canva Button. If you don't have one, sign up for an API key.

  1. Open Xcode.
  2. Select File > New > Project.
  3. Select iOS > App.
  4. Select Next.
  5. Select Interface > Storyboard.
  6. Select Life Cycle > UIKit App Delegate.
  7. Select Language > Swift.
  8. Select Next.
  9. Choose a location for the project.

Coming soon.

  1. Copy the following code snippet into the project's Podfile:

    use_frameworks!
    target 'YourApp' do
    pod 'Canva.DesignButton'
    end
    bash
  2. Run pod update.

  1. Download and extract the CanvaButton.tar.gz file. You should have received this file from Canva. The archive contains a CanvaButton.framework file, along with .bcsymbolmap and .dSYM files.
  2. Drag the CanvaButton.framework file into the Xcode project.
  3. In the Navigator, select the project.
  4. Under the Targets heading, select the target.
  5. Switch to the General tab.
  6. In the Frameworks, Libraries and Embedded content section, add the CanvaButton.framework file.
  7. Set the Embed option to Embed & Sign.

  1. Switch to the Build Phases tab.
  2. Click the + button.
  3. Select New Copy Files Phase.
  4. Expand the Copy Files panel.
  5. Set the Destination to Products Directory.
  6. Add the .bcsymbolmap and .dSYM files to the list of copied files.
  1. Click the + button.

  2. Select New Run Script Phase.

  3. Expand the Run Script panel.

  4. Copy the following command into the script editor:

    bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/CanvaButton.framework/strip.sh" "${BUILT_PRODUCTS_DIR}"
    bash
  5. Enable For install builds only.

Canva uses custom URL schemes to send information from the Canva editor to your app. URL schemes are unique values that are tied to your Canva Button API key. Canva should have already provided you with this scheme.

To set up the custom URL schemes for your app:

  1. Open the Info.plist file.
  2. Create a String property with a Key of CanvaButtonScheme.
  3. Set the URL scheme as the value of the following properties:
    • CanvaButtonScheme
    • URL Types > Item 0 > URL Schemes > Item 0

The iOS SDK provides two functions for handling custom URL schemes:

  • isInternalURL
  • handleInternalURL

You can use these functions to execute behavior in response to the information that Canva sends to your app. The exact implementation on whether or not your app uses scenes.

If your app uses scenes, import the CanvaButton module into the SceneDelegate.swift file:

import CanvaButton
swift

Then copy the following code into the SceneDelegate class:

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
for context in URLContexts {
if CanvaButton.isInternalURL(context.url) {
CanvaButton.handleInternalURL(context.url)
}
}
}
swift

If your app doesn't use scenes, import the CanvaButton module into the AppDelegate.swift file:

import CanvaButton
swift

Then copy the following code into the AppDelegate class:

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
if CanvaButton.isInternalURL(url) {
CanvaButton.handleInternalURL(url)
}
return true
}
swift

When a user opens and interacts with the Canva editor, the SDK sends information to your app. To receive this information, import the CanvaButton module into the ViewController.swift file:

import CanvaButton
swift

Then copy the following code into the ViewController.swift file:

extension ViewController: CanvaViewControllerDelegate {
func canvaViewController(_ canvaViewController: CanvaViewController, didFailToLoadWithError error: Error) {
print("Unable to load Canva editor.")
print(error)
}
func canvaViewController(_ canvaViewController: CanvaViewController, didTerminateLoadingForDesignID designID: String?) {
print("Unable to open design with an ID of \(designID ?? "nil").")
}
func canvaViewController(_ canvaViewController: CanvaViewController, didPublishDesignWithDesignID designID: String?, url: URL?) {
print("Published a design with an ID of \(designID ?? "nil").")
}
func canvaViewDidFailPublish(forDesignID designID: String?, withError error: Error) {
print("Unable to publish design with an ID of \(designID ?? "nil").")
print(error)
}
func canvaViewController(_ canvaViewController: CanvaViewController, didFinishLoadingWithDesignID designID: String) {
print("Opened a design with an ID of \(designID).")
}
}
swift

This code extends the ViewController class and implements the CanvaViewControllerDelegate protocol.

Based on this change, the following methods run throughout the lifecycle of the app:

  • didFailToLoadWithError
  • didTerminateLoadingForDesignID
  • didPublishDesignWithDesignID
  • canvaViewDidFailPublish
  • didFinishLoadingWithDesignID

The behavior of these methods is explained throughout this tutorial.

import UIKit
import CanvaButton
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
if CanvaButton.isInternalURL(url) {
CanvaButton.handleInternalURL(url)
}
return true
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return true
}
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
}
swift
import UIKit
import CanvaButton
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
for context in URLContexts {
if CanvaButton.isInternalURL(context.url) {
CanvaButton.handleInternalURL(context.url)
}
}
}
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let _ = (scene as? UIWindowScene) else { return }
}
}
swift
import UIKit
import CanvaButton
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
extension ViewController: CanvaViewControllerDelegate {
func canvaViewController(_ canvaViewController: CanvaViewController, didFailToLoadWithError error: Error) {
print("Unable to load Canva editor.")
print(error)
}
func canvaViewController(_ canvaViewController: CanvaViewController, didTerminateLoadingForDesignID designID: String?) {
print("Unable to open design with an ID of \(designID ?? "nil").")
}
func canvaViewController(_ canvaViewController: CanvaViewController, didPublishDesignWithDesignID designID: String?, url: URL?) {
print("Published a design with an ID of \(designID ?? "nil").")
}
func canvaViewDidFailPublish(forDesignID designID: String?, withError error: Error) {
print("Unable to publish design with an ID of \(designID ?? "nil").")
print(error)
}
func canvaViewController(_ canvaViewController: CanvaViewController, didFinishLoadingWithDesignID designID: String) {
print("Opened a design with an ID of \(designID).")
}
}
swift