DivingBoard
An iOS framework that provides an interface for browsing and searching for photos from Unsplash.com.
Trying out DivingBoard
This repository includes an example app named "PhotoViewer" that uses the DivingBoard framework (watch a short demo video.):
In order to run it, you'll first need to sign up for an Unsplash app ID.
Once you have an Unsplash app ID, clone or download this repository. Then open DivingBoard/ExampleApp/PhotoViewer/PhotoViewer.xcodeproj
in Xcode, and edit the file ViewController.swift
to add the ID at the top where this appears:
// let unsplashAppID = "INSERT_YOUR_APPLICATION_ID_HERE"
(If you plan on contributing to DivingBoard, see "Contributing to DivingBoard" below for a better way to do this that will keep your Unsplash app ID out of commits.)
Then you'll be able to run PhotoViewer to see how DivingBoard works.
Installing via Carthage
- Install Carthage if you don't already have it.
- In the base directory of your project, create a file named "Cartfile" containing
github "jim-rhoades/DivingBoard"
- Run
carthage update
in the terminal (in the same directory that you created the Cartfile). This will compile the framework and place it inside of your project folder atCarthage/Build/iOS/DivingBoard.framework
. - Open your project in Xcode, view your application target's "General" settings tab and scroll down to the "Embedded Binaries" section. Drag and drop the
DivingBoard.framework
file onto the "Embedded Binaries" section, and click "Finish" when prompted to.
- On your application target's "Build Phases" tab, click the "+" button to add a new build phase and choose "New Run Script Phase".
- Add the following to the script area below the shell:
/usr/local/bin/carthage copy-frameworks
- Under "Input Files" add:
$(SRCROOT)/Carthage/Build/iOS/DivingBoard.framework
- Under "Output Files" add:
$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/DivingBoard.framework
Installing via CocoaPods
- You can use CocoaPods to install DivingBoard by adding it to your Podfile:
platform :ios, '10.0'
pod 'DivingBoard', '~> 1.1.3'
- In the Terminal, navigate to the same directory that your Podfile is located, and run
pod install
. - Remember to open your Xcode project using the
.xcworkspace
file instead of the original.xcodeproj
file.
Launching DivingBoard in your app
To launch DivingBoard in your own app you'll need to get an instance of UnsplashPickerViewController
and present it. The following code shows how you would do that to present it full screen:
let unsplashAppID = "INSERT_YOUR_APPLICATION_ID_HERE"
let unsplashPicker = DivingBoard.unsplashPicker(withClientID: unsplashAppID,
presentingViewController: self,
modalPresentationStyle: .fullScreen)
present(unsplashPicker, animated: true, completion: nil)
In PhotoViewer's ViewController.swift
you'll also find examples for presenting it as a popover and pushing it onto a UINavigationController stack.
Conforming to UnsplashPickerDelegate
The view controller that you're presenting DivingBoard from also needs to conform to the UnsplashPickerDelegate
protocol, which consists of two methods:
func unsplashPickerDidCancel()
func unsplashPickerDidFinishPicking(photo: UnsplashPhoto)
See PhotoViewer's ViewController.swift
file for examples.
Adhering to the Unsplash API guidelines
It is up to you to "play nicely" and adhere to the Unsplash API Guidelines.
DivingBoard includes a couple of methods that make adhering to the "technical guidelines" part easy:
-
Call
DivingBoard.incrementUnsplashPhotoDownloadCount
if you do something like save a photo to the camera roll. This method will call the Unsplash API'sdownload_location
endpoint to increment the download count for the photo on Unsplash.com. I highly recommend reading Unsplash API Guidelines: Triggering a Download for recommendations on when to do this. (PhotoViewer uses this when saving a photo to the camera roll.) -
When linking to a photo or user on Unsplash.com, call
DivingBoard.unsplashWebsiteURLWithReferral
to get a URL with the proper attribution as described in Unsplash API Guidelines: Attribution. (PhotoViewer uses this when tapping on a photo or user avatar to view the photo/user on the Unsplash website.)
Helpful utilities
DivingBoard includes an extension on UIImageView to add the method loadImageAsync
, which will load an image asynchronously and cache it to memory/disk.
Also included is the class LoadingView
, which is a nice looking loading indicator.
You may want use either or both of these in your own app's implementation of unsplashPickerDidFinishPicking
, for example:
func unsplashPickerDidFinishPicking(photo: UnsplashPhoto) {
// show a loading indicator
let loadingView = LoadingView()
photoView.addCenteredSubview(loadingView)
// load the photo
let photoURL = photo.urls.full
photoView.loadImageAsync(with: photoURL) { success in
// remove the loading indicator
loadingView.removeFromSuperview()
}
dismiss(animated: true, completion: nil)
}
Contributing to DivingBoard
If you want to contribute to DivingBoard, I recommend that you create a file named "ClientID.swift" in the PhotoViewer Xcode project with the following content (replacing "YOUR_UNSPLASH_APP_ID" with your actual Unsplash app ID):
import Foundation
// Note that this file is in .gitignore and will NOT be added to the repository.
// (to prevent the app ID from leaking onto GitHub!)
let unsplashAppID = "YOUR_UNSPLASH_APP_ID"
Since "ClientID.swift" is included in .gitignore, that will enable you to run and test changes to DivingBoard and PhotoViewer without risk of accidentally including your Unsplash app ID in a commit.
ToDo
- [ ] change from a square grid layout to a waterfall layout that shows uncropped photos instead of square crops:
- [ ] improve the unit tests - in particular, there should be tests for UnsplashClient's
requestPhotosFor
method using a stub / fake data (the project includes files containing real JSON data from the Unsplash APIā¦test_data_photos.json
andtest_data_search.json
, but they aren't currently being used)