Skip to content
Switch branches/tags
Go to file
Cannot retrieve contributors at this time


Table of contents




Caching & Dependencies

The Grid

Clips (GIFs with Sound!) + Animated Text Creation


Github Example Repo

  • Run the example app to see the GIPHY SDK in action with all of its configurations. Run pod install and set your API key here before building the example app.
  • Open issues or feature requests
  • View releases


Add the GiphyUISDK to your Podfile like so:

target "YourAppTarget" do 
pod 'Giphy' 

Note: for pure Objective-C projects, add an empty swift file to your project and choose Create the Bridging Header when prompted by Xcode. This allows static libraries to be linked.

Swift Package Manager

Add a new Swift Package to your app linking this repo ( Swift Package Manager is supported for versions 2.1.3 and later.


We are currently unable to distribute the GIPHY SDK through Carthage. If you are using Carthage, simply drag GiphyUISDK.xcframework into your project.

You will also have to add webp support to your project.

Configure your API key

First things first, be sure to import:

import GiphyUISDK 

Configure your API key. Apply for a new iOS SDK key here. Please remember, you should use a separate key for every platform (Android, iOS, Web) you add our SDKs to.

Giphy.configure(apiKey: "your ios sdk key here")

Custom UI

We offer two solutions for the SDK user interface - pre-built templates which handle the entirety of the GIPHY experience, and a Grid-Only implementation which allows for endless customization.

See customization to determine what's best for you.

Skip ahead to Grid-Only section


Create a new GiphyViewController, which takes care of most of the magic.

let giphy = GiphyViewController()

Create a new GiphyViewController every time you want to show GIPHY (maintaining a reference to the same GiphyViewController object isn't necesssary and can impact performance and lead to unexpected results)

Template Settings

Media Types

Set the content type(s) you'd like to show by setting the mediaTypeConfig property, which is an array of GPHContentTypes.

giphy.mediaTypeConfig = [.gifs, .stickers, .text, .emoji]


[giphy setMediaConfigWithTypes: [[ NSMutableArray alloc] initWithObjects: 
@(GPHContentTypeGifs), @(GPHContentTypeStickers), @(GPHContentTypeText), @(GPHContentTypeEmoji), nil ] ]; 

Recently Picked

As of v1.2.5, you can add an additional GPHContentType to the mediaTypeConfig array: .recents

giphy.mediaTypeConfig = [.gifs, .stickers, .recents]

GIFs that are selected by the user are automatically added to the recents tab, which is only displayed if the user has previously picked a gif.

Users can remove gifs from recents with a long-press on the GIF in the recents grid.


Set the theme type (GPHThemeType) to be .dark, .light, .lightBlur, .darkBlur or .automatic. The automatic option follows the current Dark Mode setting of the device.

giphy.theme = GPHTheme(type: .lightBlur) 

For video editing apps, we recommend trying out .lightBlur or .darkBlur themes.

Extending GPHTheme

As of version 1.2.8, you can also subclass GPHTheme to override visual properties like font and colors, so as to apply the visual language of your app.

public class CustomTheme: GPHTheme {
    public override init() {
        self.type = .light
    public override var textFieldFont: UIFont? {
        return UIFont.italicSystemFont(ofSize: 15.0)

    public override var textColor: UIColor {
        return .black

Additional Settings

  • Sticker Column Count: We provide the option to set the number of columns for stickers and text. Possible GPHStickerColumnCountvalues are .two, .three. and .four. We recommend going for 3 or 4 columns when leveraging the blur GPHThemeType.
giphy.stickerColumnCount = GPHStickerColumnCount.three 
  • Confirmation screen: we provide the option to show a secondary confirmation screen when the user taps a GIF, which shows a larger rendition of the asset.
giphy.showConfirmationScreen = true 
  • Rating: set a specific content rating for the search results. Default ratedPG13.
giphy.rating = .ratedPG13
  • Rendition: option to select the rendition type for the grid. Default fixedWidth.
giphy.renditionType = .fixedWidth 
  • Localization: option to choose whether or not to localize the search results based on phone settings. Default false will set the language to en.
giphy.shouldLocalizeSearch = false
  • Tray Height: height for the tray's "snap point" as a ratio of the GiphyViewController's height. Default 0.7
GiphyViewController.trayHeightMultiplier = 0.7 


Present the GiphyViewController and watch as the GIFs start flowin'.

present(giphy, animated: true, completion: nil)


Set the delegate and conform to the GiphyDelegate protocol to handle GIF selection.

giphy.delegate = self
extension YourController: GiphyDelegate { 
   func didSelectMedia(giphyViewController: GiphyViewController, media: GPHMedia)   {
        // your user tapped a GIF!   
        giphyViewController.dismiss(animated: true, completion: nil) 
   func didDismiss(controller: GiphyViewController?) {
        // your user dismissed the controller without selecting a GIF.  

From there, it's up to you to decide what to do with the GIF!


Create a GPHMediaView to display the media:

let mediaView = GPHMediaView() = media  

Use the media's aspectRatio property to size the view:

let aspectRatio = media.aspectRatio 

If you want to build your own view to display a GIF, grab a URL to the asset like so:

let webpURL = media.url(rendition: .original, fileType: .webp) 
let gifURL = media.url(rendition: .fixedWidth, fileType: .gif) 
let vidURL = media.url(rendition: .fixedWidth, fileType: .mp4) 

let url = URL(string: gifURL) 

Media IDs

In a messaging app context, you may want to send media ids rather than GPHMedia objects or image assets.

Obtain a GPHMedia's id property via

On the receiving end, obtain a GPHMedia from the id like so:

GiphyCore.shared.gifByID(id) { (response, error) in
    if let media = response?.data {
        DispatchQueue.main.sync { [weak self] in 
            self? = media


We use URLCache to cache media assets, which reduces unnecessary image requests and loading times.

The URLCache disk and memory components are both limited to 300 mb by default, but you can set them to any values you’d like:

// set to 300 mb 
GPHCache.shared.cache.diskCapacity = 300 * 1000 * 1000  
GPHCache.shared.cache.memoryCapacity = 300 * 1000 * 1000   

Note: We don't automatically clear the cache when the GiphyViewController is dismissed. Manually clear the cache by calling GPHCache.shared.clear() to clear the cache

The cache storesData objects for the images (the SDK displays .webp files by default). You can get the raw image data yourself via:

guard let url = media.url(rendition: .fixedWidth, fileType: .webp) else { return } 
GPHCache.shared.downloadAssetData(url) { (data, error) in


YYImage: GIF playback
libwebp: webp playback


Download the Sketch file here if you're looking for a great button icon to prompt the GIPHY SDK experience.

Grid-Only and the GiphyGridController Setup

The following section refers to the Grid-Only solution of the SDK. Learn more here

See the Template section for template setup instructions.

The GiphyGridController takes care of requesting content from the GIPHY API, loading, caching, and rendering images in a customizable grid, and leaves the rest of the experience up to you.

The GiphyGridController offers more customization of the grid than the GiphyViewController, via the numberOfTracks, cellPadding, and direction properties.

Create a new grid controller:

let gridController = GiphyGridController()

Customize the grid design:

// space between cells 
gridController.cellPadding = 2.0

// the scroll direction of the grid 
gridController.direction = .vertical 

// the number of "tracks" is the span count. it represents num columns for vertical grids & num rows for horizontal grids 
gridController.numberOfTracks = 3

// hide the checkered background for stickers if you'd like (true by default) 
gridController.showCheckeredBackground = false 
gridController.view.backgroundColor = .lightGray

// by default, the waterfall layout sizes cells according to the aspect ratio of the media 
// the fixedSizeCells setting makes it so each cell is square
// this setting only applies to Stickers (not GIFs) 
gridController.fixedSizeCells = true 

GiphyGridController: Presentation

Unlike the GiphyViewController, the GiphyGridController is not by itself a fully functional component, and must exist alongside other UI in order to offer a meaningful user experience. We recommend embedding the GiphyGridController inside of another UIViewController by adding it as a child view controller, adding its subview, and constraining it according to your design.

Important For performance reasons, a new GiphyGridController should be created every time the Giphy search experience is presented, and the instance should be always set to nil when it is dismissed. Ensure that there is only ever one instance of a GiphyGridController allocated at a given screen - multiple instances of GiphyGridControllers may not be added to the same screen.


gridController.view.translatesAutoresizingMaskIntoConstraints = false

gridController.view.leftAnchor.constraint(equalTo: view.safeLeftAnchor).isActive = true
gridController.view.rightAnchor.constraint(equalTo: view.safeRightAnchor).isActive = true
gridController.view.topAnchor.constraint(equalTo: view.safeTopAnchor).isActive = true
gridController.view.bottomAnchor.constraint(equalTo: view.safeBottomAnchor).isActive = true

gridController.didMove(toParent: self)

GiphyGridController: GPHContent

The GiphyGridController comes with a new class GPHContent. A GPHContent describes a content request to the Giphy API.

Create content objects with GPHContent class methods, like so:


let trendingGIFs = GPHContent.trending(mediaType: .gif) 
let trendingStickers = GPHContent.trending(mediaType: .sticker) 
let trendingText = GPHContent.trending(mediaType: .text)


let emoji = GPHContent.emoji


let search = "Hello", mediaType: .gif, language: .english)


Show GIFs that the user has previously picked.

let recentlyPicked = GPHContent.recents 

Only show a "recents" tab if there are any recents. Get the number of recents via:

let numberOfRecents = GPHRecents.count 

Optionally, we also provide the option to clear the set of recents:


Updating the content

Set the grid controller's content property and call update:

gridController.content = "Sup", mediaType: .text, language: .english)

GiphyGridController: GPHGridDelegate

Similar to the GiphyDelegate, the GPHGridDelegate is the mechanism for responding to gif selection events in the grid.

Conform to the GPHGridDelegate and set the delegate.

gridController.delegate = self
extension ViewController: GPHGridDelegate {
    func contentDidUpdate(resultCount: Int) {
        print("content did update")
    func didSelectMedia(media: GPHMedia, cell: UICollectionViewCell) {
        print("did select media")

Data Collected by our SDK


Apple will require developers to provide information about their app’s privacy practices in App Store Connect, including the practices of third-party partners whose code is integrated into their app. To make this process easier for you, we’ve provided the following list of boxes you will be required check when submitting your app to the App Store if your app integrates the GIPHY SDK.

We deeply respect the privacy of your users and only collect anonymized information about GIPHY use in order to improve the service. If you have any questions or concerns about GIPHY’s data collection practices, please reach out to

Title Description Data use Linked to user Tracking
Search History Information about searches performed in the app Analytics, Product Personalization, App Functionality No No
Product Interaction Such as app launches, taps, clicks, scrolling information, music listening data, video views, saved place in a game, video, or song, or other information about how the user interacts with the app Analytics, Product Personalization, App Functionality No No