Swift Photo App Slack

minio_SWIFT1

This example will guide you through the code to build a simple Swift Photo app. In this app, you will learn how a Swift client can use the Photo API Service and load a random image. Full code is available here: https://github.com/minio/swift-photo-app, released under Apache 2.0 License.

1. Dependencies

We will be building this app using Xcode 7.0 with Swift 2.0. This app will also consume the Photo API Service we built to get presigned urls that are randomly loaded on click of a button.

2. SetUp

Launch Xcode and complete the following steps.

minio_SWIFT2

minio_SWIFT3

minio_SWIFT4

3. MainStoryBoard

minio_SWIFT5

4. ViewController.swift

We will use the Photo API Service we built earlier to service the SwiftPhotoApp client. For the sake of simplicity, we will not use a TableView or a CollectionView to display all of the photos. Instead we will randomly load one of the photos from the presigned URLs we receive from the PhotoAPI Service.

import UIKit

class ViewController: UIViewController {

    @IBAction func refButton(sender: UIButton) {

        // Set up the URL Object.
        let url = URL(string: "http://play.minio.io:8080/PhotoAPIService-0.0.1-SNAPSHOT/minio/photoservice/list")

        // Task fetches the url contents asynchronously.
        let task = URLSession.shared.dataTask(with: url! as URL) {(data, response, error) in

            let httpResponse = response as! HTTPURLResponse
            let statusCode = httpResponse.statusCode

            // Process the response.
            if (statusCode == 200) {

                do{
                    // Get the json response.
                    let json = try JSONSerialization.jsonObject(with: data!, options:.allowFragments) as! [String:AnyObject]

                    // Extract the Album json into the albums array.
                    if let albums = json["Album"] as? [[String: AnyObject]]{

                        // Pick a random index from the albums array.
                        let randomIndex = Int(arc4random_uniform(UInt32(albums.count)))

                        // Extract the url from the albums array using this random index we generated.
                        let loadImageUrl:String = albums[randomIndex]["url"]  as! String

                        // Prepare the imageView.
                        self.imageView.contentMode = .scaleAspectFit

                        // Download and place the image in the image view with a helper function.
                        if let checkedUrl = URL(string: loadImageUrl) {
                            self.imageView.contentMode = .scaleAspectFit
                            self.downloadImage(url: checkedUrl)
                        }

                    }
                }
                catch {
                    print("Error with Json: \(error)")
                }
            }

        }

        task.resume()

    }

    @IBOutlet weak var imageView: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // Asynchronous helper function that fetches data from the PhotoAPIService.
    func getDataFromUrl(url:URL, completion: @escaping ((_ data: Data?, _ response: URLResponse?, _ error: Error? ) -> Void)) {
        URLSession.shared.dataTask(with: url as URL) { (data, response, error) in
            completion(data, response, error)
            }.resume()
    }

    // Helper function that download asynchronously an image from a given url.
    func downloadImage(url: URL){
        getDataFromUrl(url: url) { (data, response, error)  in
            DispatchQueue.main.async() { () -> Void in
                guard let data = data, error == nil else { return }
                self.imageView.image = UIImage(data: data as Data)
            }
        }
    }

}

5. Info.plist

We need to add the permissions into our info.plist file so that the app can fetch the URLs & images from play.

minio_SWIFT6

Here's the full info.plist file if you prefer to see the xml version of the above changes.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>en</string>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>$(PRODUCT_NAME)</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>1</string>
    <key>LSRequiresIPhoneOS</key>
    <true/>
    <key>UILaunchStoryboardName</key>
    <string>LaunchScreen</string>
    <key>UIMainStoryboardFile</key>
    <string>Main</string>
    <key>UIRequiredDeviceCapabilities</key>
    <array>
        <string>armv7</string>
    </array>
    <key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>

    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExceptionDomains</key>
        <dict>
            <key>play.minio.io</key>
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
                <true/>
                <key>NSTemporaryExceptionMinimumTLSVersion</key>
                <string>1.0</string>
                <key>NSTemporaryExceptionRequiresForwardSecrecy</key>
                <false/>
            </dict>
        </dict>
    </dict>
</dict>

</plist>

7. Run the App

8. Explore Further