Setup
Templates
GPHMedia
Caching & Dependencies
The Grid
Clips (GIFs with Sound!) + Animated Text Creation
- iOS 13.0 or later
- A Giphy API key from the Giphy Developer Portal.
- Xcode 12 and later
- 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'
end
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.
Add a new Swift Package to your app linking this repo (https://github.com/Giphy/giphy-ios-sdk
).
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.
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")
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)
Set the content type(s) you'd like to show by setting the mediaTypeConfig
property, which is an array of GPHContentType
s.
giphy.mediaTypeConfig = [.gifs, .stickers, .text, .emoji]
Objective-C:
[giphy setMediaConfigWithTypes: [[ NSMutableArray alloc] initWithObjects:
@(GPHContentTypeGifs), @(GPHContentTypeStickers), @(GPHContentTypeText), @(GPHContentTypeEmoji), nil ] ];
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.
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() {
super.init()
self.type = .light
}
public override var textFieldFont: UIFont? {
return UIFont.italicSystemFont(ofSize: 15.0)
}
public override var textColor: UIColor {
return .black
}
}
Version 2.2.5 offers a wider range of colors for customization. We have made modifications to the color names, but we have prepared a visual scheme to assist you with this update.
public class ExampleTheme: GPHTheme {
public override init() {
super.init()
self.type = .automatic
}
public override var searchPlaceholderTextColor: UIColor {
switch mode {
case .dark, .darkBlur:
return .blue
case .light, .lightBlur:
return .green
default:
return .clear
}
}
var mode: GPHThemeType {
if case .automatic = type {
if isDarkMode {
return .dark
}
return .light
}
return type
}
}
- Sticker Column Count: We provide the option to set the number of columns for stickers and text. Possible
GPHStickerColumnCount
values are.two
,.three
. and.four
. We recommend going for 3 or 4 columns when leveraging the blurGPHThemeType
.
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 toen
.
giphy.shouldLocalizeSearch = false
- Tray Height: height for the tray's "snap point" as a ratio of the
GiphyViewController
's height. Default0.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()
mediaView.media = 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)
In a messaging app context, you may want to send media id
s rather than GPHMedia
objects or image assets.
Obtain a GPHMedia
's id
property via media.id
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?.mediaView.media = 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.
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
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 GiphyGridController
s may not be added to the same screen.
addChild(gridController)
view.addSubview(gridController.view)
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)
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 = GPHContent.search(withQuery: "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:
GPHRecents.clear()
Set the grid controller's content
property and call update:
gridController.content = GPHContent.search(withQuery: "Sup", mediaType: .text, language: .english)
gridController.update()
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")
}
}
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 developers@giphy.com
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 |