Skip to content
This repository has been archived by the owner on Jul 31, 2024. It is now read-only.

Commit

Permalink
Merge pull request #189 from vimeo/release/2.0.0
Browse files Browse the repository at this point in the history
Release v2.0.0
  • Loading branch information
nicolelehrer authored Aug 29, 2018
2 parents a3fce76 + 427dd14 commit d8259de
Show file tree
Hide file tree
Showing 151 changed files with 4,277 additions and 3,713 deletions.
57 changes: 57 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
version: 2

jobs:
build-and-test:
environment:
BUNDLE_PATH: vendor/bundle
FL_OUTPUT_DIR: output
macos:
xcode: "9.4.1"
working_directory: ~/VimeoUpload
shell: /bin/bash --login -o pipefail

steps:
- checkout

- restore_cache:
key: v1-gems-{{ checksum "Gemfile.lock" }}

- run:
name: Set Ruby version
command: echo "ruby-2.4" > ~/.ruby-version

- run:
name: Install bundler dependencies
command: bundle install --path vendor/bundle

- run:
name: Build and run VimeoUpload-iOS tests
command: bundle exec fastlane scan
environment:
SCAN_DEVICE: iPhone 8
SCAN_SCHEME: VimeoUpload-iOS

- run:
name: Build and run VimeoUpload-iOS-OldUpload tests
command: bundle exec fastlane scan
environment:
SCAN_DEVICE: iPhone 8
SCAN_SCHEME: VimeoUpload-iOS-OldUpload

- save_cache:
paths:
- vendor/bundle
key: v1-gems-{{ checksum "Gemfile.lock" }}

- store_artifacts:
path: output

- store_test_results:
path: output/scan

workflows:
version: 2
build:
jobs:
- build-and-test

2 changes: 1 addition & 1 deletion Examples/VimeoUpload+Demos/Cells/DemoCameraRollCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class DemoCameraRollCell: UICollectionViewCell, CameraRollAssetCell

if seconds > 0
{
string = String.stringFromDuration(inSeconds: seconds) as String
string = NSString.stringFromDuration(inSeconds: seconds) as String
}

self.durationlabel?.text = string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,123 +31,42 @@ import VimeoNetworking
import AFNetworking
import VimeoUpload

typealias UploadUserAndCameraRollAsset = (user: VIMUser, cameraRollAsset: VIMPHAsset)

/*
This viewController displays the device camera roll video contents.

It starts an operation on load that requests a fresh version of the authenticated user, checks that user's daily quota, and if the user selects a non-iCloud asset it checks the weekly quota and available diskspace.

Essentially, it performs all checks possible at this UX juncture to determine if we can proceed with the upload.

[AH] 12/03/2015
*/

class BaseCameraRollViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout
{
static let NibName = "BaseCameraRollViewController"
private static let CollectionViewSpacing: CGFloat = 2

var sessionManager: VimeoSessionManager!
var sessionManager: VimeoSessionManager?

// MARK:

@IBOutlet weak var collectionView: UICollectionView!
@IBOutlet weak var activityIndicatorView: UIActivityIndicatorView!


// MARK:

private var assets: [VIMPHAsset] = []
private var cameraRollAssetHelper: PHAssetHelper?
private var operation: MeQuotaOperation?
private var me: VIMUser? // We store this in a property instead of on the operation itself, so that we can refresh it independent of the operation [AH]
private var meOperation: MeOperation?
private var selectedIndexPath: IndexPath?

// MARK: Lifecycle

deinit
{
self.removeObservers()
self.meOperation?.cancel()
self.operation?.cancel()
}

override func viewDidLoad()
{
super.viewDidLoad()

self.cameraRollAssetHelper = PHAssetHelper()
self.assets = self.loadAssets()

self.addObservers()

self.setupNavigationBar()
self.setupCollectionView()
self.setupAndStartOperation()
}

override func viewDidAppear(_ animated: Bool)
{
super.viewDidAppear(animated)

if let indexPath = self.selectedIndexPath // Deselect the previously selected item upon return from video settings
{
self.collectionView.deselectItem(at: indexPath, animated: true)
}
}

// MARK: Observers

private func addObservers()
{
NotificationCenter.default.addObserver(self, selector: #selector(UIApplicationDelegate.applicationWillEnterForeground(_:)), name: Notification.Name.UIApplicationWillEnterForeground, object: nil)
}

private func removeObservers()
{
NotificationCenter.default.removeObserver(self, name: Notification.Name.UIApplicationWillEnterForeground, object: nil)
self.collectionView.indexPathsForSelectedItems?.forEach({ self.collectionView.deselectItem(at: $0, animated: true) })
}

// Ensure that we refresh the me object on return from background
// In the event that a user modified their upload quota while the app was backgrounded [AH] 12/06/2015

func applicationWillEnterForeground(_ notification: Notification)
{
if self.meOperation != nil
{
return
}

let operation = MeOperation(sessionManager: self.sessionManager)
operation.completionBlock = { [weak self] () -> Void in

DispatchQueue.main.async(execute: { [weak self] () -> Void in

guard let strongSelf = self else
{
return
}

strongSelf.meOperation = nil

if operation.isCancelled == true
{
return
}

if operation.error != nil
{
return
}

strongSelf.me = operation.result!
})
}

self.meOperation = operation
operation.start()
}

// MARK: Setup

private func loadAssets() -> [VIMPHAsset]
Expand Down Expand Up @@ -181,48 +100,6 @@ class BaseCameraRollViewController: UIViewController, UICollectionViewDataSource
layout?.minimumLineSpacing = BaseCameraRollViewController.CollectionViewSpacing
}

private func setupAndStartOperation()
{
let operation = MeQuotaOperation(sessionManager: self.sessionManager, me: self.me)
operation.completionBlock = { [weak self] () -> Void in

DispatchQueue.main.async(execute: { [weak self] () -> Void in

guard let strongSelf = self else
{
return
}

if operation.isCancelled == true
{
return
}

strongSelf.activityIndicatorView.stopAnimating()

if let error = operation.error
{
if let indexPath = strongSelf.selectedIndexPath
{
strongSelf.presentErrorAlert(at: indexPath, error: error)
}
// else: do nothing, the error will be communicated at the time of cell selection
}
else
{
let indexPath = strongSelf.selectedIndexPath!
let cameraRollAsset = strongSelf.assets[indexPath.item]
strongSelf.me = operation.me!

strongSelf.finish(cameraRollAsset: cameraRollAsset)
}
})
}

self.operation = operation
self.operation?.start()
}

// MARK: UICollectionViewDataSource

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
Expand Down Expand Up @@ -262,48 +139,26 @@ class BaseCameraRollViewController: UIViewController, UICollectionViewDataSource

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
{
self.didSelect(indexPath: indexPath)
}

// MARK: Private API

private func didSelect(indexPath: IndexPath)
{
let cameraRollAsset = self.assets[indexPath.item]
let asset = self.assets[indexPath.item]

// Check if an error occurred when attempting to retrieve the asset
if let error = cameraRollAsset.error

if let error = asset.error
{
self.presentAssetErrorAlert(at: indexPath, error: error)

return
}

self.selectedIndexPath = indexPath

if let error = self.operation?.error
if AFNetworkReachabilityManager.shared().isReachable == false
{
let error = NSError(domain: NSURLErrorDomain, code: NSURLErrorNotConnectedToInternet, userInfo: [NSLocalizedDescriptionKey: "The internet connection appears to be offline."])
self.presentErrorAlert(at: indexPath, error: error)
}
else
{
if AFNetworkReachabilityManager.shared().isReachable == false
{
let error = NSError(domain: NSURLErrorDomain, code: NSURLErrorNotConnectedToInternet, userInfo: [NSLocalizedDescriptionKey: "The internet connection appears to be offline."])
self.presentErrorAlert(at: indexPath, error: error)

return
}

// Only show the activity indicator UI if the network request is in progress
if self.operation?.me == nil
{
self.activityIndicatorView.startAnimating()
}

// The avAsset may or may not be nil, which is fine. Becuase at the very least this operation needs to fetch "me"
self.operation?.fulfillSelection(avAsset: cameraRollAsset.avAsset)
return
}

self.didSelect(asset)
}

// MARK: UI Presentation
Expand All @@ -328,9 +183,7 @@ class BaseCameraRollViewController: UIViewController, UICollectionViewDataSource
return
}

strongSelf.selectedIndexPath = nil
strongSelf.collectionView.deselectItem(at: indexPath, animated: true)
strongSelf.setupAndStartOperation()
strongSelf.collectionView.indexPathsForSelectedItems?.forEach({ strongSelf.collectionView.deselectItem(at: $0, animated: true) })
}))

alert.addAction(UIAlertAction(title: "Try Again", style: UIAlertActionStyle.default, handler: { [weak self] (action) -> Void in
Expand All @@ -339,24 +192,12 @@ class BaseCameraRollViewController: UIViewController, UICollectionViewDataSource
{
return
}

strongSelf.setupAndStartOperation()
strongSelf.didSelect(indexPath: indexPath)

strongSelf.collectionView(strongSelf.collectionView, didSelectItemAt: indexPath)
}))

self.present(alert, animated: true, completion: nil)
}

private func finish(cameraRollAsset: VIMPHAsset)
{
let me = self.me!

// Reset the operation so we're prepared to retry upon cancellation from video settings [AH] 12/06/2015
self.setupAndStartOperation()

let result = UploadUserAndCameraRollAsset(user: me, cameraRollAsset: cameraRollAsset)
self.didFinish(with: result)
}

// MARK: Overrides

Expand All @@ -365,7 +206,7 @@ class BaseCameraRollViewController: UIViewController, UICollectionViewDataSource
self.title = "Camera Roll"
}

func didFinish(with result: UploadUserAndCameraRollAsset)
func didSelect(_ asset: VIMPHAsset)
{
assertionFailure("Subclasses must override")
}
Expand Down
Loading

0 comments on commit d8259de

Please sign in to comment.