Created
July 1, 2016 11:50
-
-
Save hprobotic/e601cf599d5c654e7ea01fa5bc01be02 to your computer and use it in GitHub Desktop.
Test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// APIRouter.swift | |
// PicPic | |
// | |
// Created by Johnny Pham on 6/20/16. | |
// Copyright © 2016 John Pham. All rights reserved. | |
// | |
import Foundation | |
import Alamofire | |
enum APIRouter: URLRequestConvertible { | |
static let baseURLString: String = "https://api.parse.com/1/classes" | |
case GetAtPath(String) | |
case GetListPoll([String: AnyObject]) // GET https://api.parse.com/1/classes/Poll | |
case GetListTag() // GET https://api.parse.com/1/classes/Tag | |
case GetListPhoto() // GET https://api.parse.com/1/classes/Photo | |
case GetListUser() // GET https://api.parse.com/1/classes/User | |
case CreateNewPoll([String: AnyObject]) // POST https://api.parse.com/1/classes/Poll | |
case VoteForPoll(String) // PUT https://api.parse.com/1/classes/Poll | |
case PostImageURL([String: AnyObject]) // POST https://api.parse.com/1/classes/Photo | |
var URLRequest: NSMutableURLRequest { | |
var method: Alamofire.Method { | |
switch self { | |
case .GetAtPath, .GetListUser, .GetListTag, .GetListPhoto, .GetListUser: | |
return .GET | |
case .CreateNewPoll, .PostImageURL: | |
return .POST | |
case .VoteForPoll: | |
return .PUT | |
default: | |
return .GET | |
} | |
} | |
let url: NSURL = { | |
let relativePath: String? | |
switch self { | |
case .GetAtPath(let path): | |
return NSURL(string: path)! | |
case .GetListPoll: | |
relativePath = "/Poll" | |
case .GetListTag: | |
relativePath = "/Tag" | |
case .GetListPhoto: | |
relativePath = "/Photo" | |
case .GetListUser: | |
relativePath = "/User" | |
case .CreateNewPoll: | |
relativePath = "/Poll" | |
case .PostImageURL: | |
relativePath = "/Photo" | |
default: | |
relativePath = "" | |
} | |
var URL = NSURL(string: APIRouter.baseURLString)! | |
if let relativePath = relativePath { | |
URL = URL.URLByAppendingPathComponent(relativePath) | |
} | |
return URL | |
}() | |
var encoding: ParameterEncoding { | |
switch self { | |
case .GetListPoll: | |
return .URL | |
default: | |
return .JSON | |
} | |
} | |
let params: ([String: AnyObject]?) = { | |
switch self { | |
case .GetAtPath, .GetListUser, .GetListTag, .GetListPhoto, .GetListUser, .GetListPoll: | |
return (nil) | |
case .CreateNewPoll(let params): | |
return (params) | |
case .PostImageURL(let params): | |
return (params) | |
default: | |
return (nil) | |
} | |
}() | |
let URLRequest = NSMutableURLRequest(URL: url) | |
// Set Application and rest api key | |
let appID = AppAPIManager.sharedInstance.applicationID | |
let restAPIKey = AppAPIManager.sharedInstance.restAPIKey | |
URLRequest.setValue("\(appID)", forHTTPHeaderField: "X-Parse-Application-Id") | |
URLRequest.setValue("\(restAPIKey)", forHTTPHeaderField: "X-Parse-REST-API-Key") | |
let (encodedRequest, _) = encoding.encode(URLRequest, parameters: params) | |
encodedRequest.HTTPMethod = method.rawValue | |
return encodedRequest | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AppAPIManager.swift | |
// PicPic | |
// | |
// Created by Johnny Pham on 6/16/16. | |
// Copyright © 2016 John Pham. All rights reserved. | |
// | |
import Foundation | |
import Alamofire | |
import SwiftyJSON | |
import MBProgressHUD | |
import AmazonS3RequestManager | |
class AppAPIManager { | |
static let sharedInstance = AppAPIManager() | |
var alamofireManager: Alamofire.Manager | |
static let ErrorDomain = "com.error.AppAPIManager" | |
//Parse | |
let applicationID = "XZredF1dVBUyCLZ32LMGYhbp1kVJ2DpQ07pRayL3" | |
let restAPIKey = "MWHofXuC3lEAa5SJCOBrH1YQ0oZ7rxopCgnB7ROH" | |
//AWS S3 | |
let s3Bucket = "picpic-production" | |
let s3Region = AmazonS3Region.APSoutheast1 | |
let s3AccessKey = "AKIAI6QI3XOZCATK5W6Q" | |
let s3Secret = "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" | |
private let amazonS3Manager: AmazonS3RequestManager! | |
init () { | |
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() | |
alamofireManager = Alamofire.Manager(configuration: configuration) | |
amazonS3Manager = AmazonS3RequestManager(bucket: s3Bucket, | |
region: s3Region, | |
accessKey: s3AccessKey, | |
secret: s3Secret) | |
} | |
// Mark: Tags | |
func getTags(completionHandler: ([Tag]?) -> Void) { | |
alamofireManager.request(APIRouter.GetListTag()) | |
.validate() | |
.responseJSON { (response) in | |
switch response.result { | |
case .Success(let data): | |
let results = data["results"] as! [[String: AnyObject]] | |
var tags = [Tag]() | |
for item in results { | |
tags.append(Tag(json: JSON(item))!) | |
} | |
completionHandler(tags) | |
case .Failure(let error): | |
log.error("Request failed with error: \(error)") | |
} | |
} | |
} | |
// Mark: Images | |
// Upload image to AWS S3 | |
func uploadImageData(imageData: NSData, folderName: String, completion: (nsurl: NSURL) -> Void) { | |
let fileName = "\(NSUUID().UUIDString).jpg" | |
amazonS3Manager.putObject(imageData, destinationPath: "\(folderName)/\(fileName)").responseS3Data { response in | |
if response.result.error == nil { | |
completion(nsurl: (response.response?.URL)!) | |
} | |
} | |
} | |
// Save Image URL database | |
func saveImageURL(imageURL: String, completionHandler: | |
(ApiResult?, NSError?) -> Void) { | |
let parameters:[String: AnyObject] = [ | |
"imageURL": imageURL | |
] | |
alamofireManager.request(APIRouter.PostImageURL(parameters)) | |
.responseJSON { (response) in | |
switch response.result { | |
case .Success(let data): | |
let apiResult = ApiResult() | |
apiResult.objectId = data["objectId"] as? String | |
apiResult.createdAt = data["objectId"] as? String | |
completionHandler(apiResult, nil) | |
case .Failure(let error): | |
log.error("Request failed with error: \(error)") | |
} | |
} | |
} | |
// Create new poll | |
func createNewPoll(pollTitle: String, imageLeftObjectId: String, imageRightObjectId: String, tags: [String], completionHandler: (ApiResult?, NSError?) -> Void) { | |
let parameters:[String: AnyObject] = [ | |
"title": pollTitle, | |
"isPrivate": false, | |
"user": [ | |
"__type": "Pointer", | |
"className": "_User", | |
"objectId": "E55GdH5zGM" | |
], | |
"tags": tags, | |
"photos": [ | |
[ | |
"__type": "Pointer", | |
"className": "Photo", | |
"objectId": imageLeftObjectId | |
], | |
[ | |
"__type": "Pointer", | |
"className": "Photo", | |
"objectId": imageRightObjectId | |
] | |
], | |
] | |
alamofireManager.request(APIRouter.CreateNewPoll(parameters)) | |
.responseJSON { (response) in | |
switch response.result { | |
case .Success(let data): | |
let apiResult = ApiResult() | |
apiResult.objectId = data["objectId"] as? String | |
apiResult.createdAt = data["objectId"] as? String | |
completionHandler(apiResult, nil) | |
case .Failure(let error): | |
log.error("Request failed with error: \(error)") | |
} | |
} | |
} | |
// Get list poll | |
func getPolls(completionHandler: ([Poll]?) -> Void) { | |
let parameters:[String: AnyObject] = [ | |
"include": "photos" | |
] | |
alamofireManager.request(APIRouter.GetListPoll(parameters)) | |
.validate() | |
.responseJSON { (response) in | |
switch response.result { | |
case .Success(let data): | |
let results = data["results"] as! [[String: AnyObject]] | |
var polls = [Poll]() | |
for item in results { | |
polls.append(Poll(json: JSON(item))!) | |
print(item) | |
} | |
completionHandler(polls) | |
case .Failure(let error): | |
log.error("Request failed with error: \(error)") | |
} | |
} | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// PollCollectionViewController.swift | |
// PicPic | |
// | |
// Created by Johnny Pham on 6/16/16. | |
// Copyright © 2016 John Pham. All rights reserved. | |
// | |
import UIKit | |
import Alamofire | |
import AlamofireImage | |
private let reuseIdentifier = "Cell" | |
class PollCollectionViewController: UICollectionViewController { | |
var localPlaceHolderImageName = "image-placeholder" | |
private var currentIndex: CFloat = 0 | |
private var pageControl: UIPageControl! | |
private var finishedSetup: Bool = false | |
private let kPageControlHeight: CGFloat = 30 | |
private var autoScrollingEnabled = false | |
private var circularScrollingEnabled = true | |
var polls: [Poll] = [] | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
self.setUpCollectionView() | |
self.setUpPlaceHolderItem() | |
// AppAPIManager.sharedInstance.getPolls().then { polls -> Void in | |
// self.polls = polls | |
// self.refresh() | |
// } | |
AppAPIManager.sharedInstance.getPolls { (result) in | |
self.polls = result! | |
self.refresh() | |
} | |
} | |
override func viewDidLayoutSubviews() { | |
if(finishedSetup == false) { | |
self.setCollectionViewStartingOffset() | |
finishedSetup = true | |
} | |
} | |
override func viewDidAppear(animated: Bool) { | |
collectionView?.reloadData() | |
} | |
private func setUpPlaceHolderItem() { | |
setUpDataForCircularCarouselCollectionView() | |
} | |
func refresh() { | |
self.setCollectionViewStartingOffset() | |
self.collectionView!.reloadData() | |
} | |
override func didReceiveMemoryWarning() { | |
super.didReceiveMemoryWarning() | |
} | |
private func setUpDataForCircularCarouselCollectionView() { | |
if (circularScrollingEnabled == true) { | |
if (self.polls.count > 0) { | |
let dataSize = self.polls.count | |
let firstItem = self.polls[0] | |
let lastItem = self.polls[dataSize - 1] | |
self.polls.insert(lastItem, atIndex: 0) | |
self.polls.append(firstItem) | |
} | |
} | |
} | |
private func setUpCollectionView() { | |
self.collectionView!.showsHorizontalScrollIndicator = false | |
let carouselCollectionViewFlowLayout: PollCollectionViewFlowLayout = PollCollectionViewFlowLayout() | |
self.collectionView!.setCollectionViewLayout(carouselCollectionViewFlowLayout, animated: false) | |
let nib: UINib = UINib(nibName: "PollCollectionViewCell", bundle: nil) | |
self.collectionView!.registerNib(nib, forCellWithReuseIdentifier: "carouselCell") | |
} | |
private func setCollectionViewStartingOffset() { | |
if(circularScrollingEnabled == true) { | |
self.collectionView!.setContentOffset(CGPointMake(self.collectionView!.frame.size.width, 0), animated: false) | |
} | |
} | |
func nextItem() { | |
let pageWidth: CGFloat = self.collectionView!.frame.size.width | |
let contentOffset: CGFloat = self.collectionView!.contentOffset.x | |
let nextPage: CGFloat = (contentOffset / pageWidth) + 1 | |
let newOffset: CGPoint = CGPointMake(pageWidth * nextPage, 0) | |
if(circularScrollingEnabled == false) { | |
if(Int(nextPage) <= (self.polls.count - 1)) { | |
self.collectionView!.setContentOffset(newOffset, animated: true) | |
} | |
} else { | |
self.collectionView!.setContentOffset(newOffset, animated: true) | |
} | |
} | |
func disableCircularScrolling() { | |
circularScrollingEnabled = false | |
} | |
func disableAutoScrolling() { | |
autoScrollingEnabled = false | |
} | |
override func scrollViewDidScroll(scrollView: UIScrollView) { | |
if(finishedSetup == true) { | |
self.checkPage(scrollView) | |
self.checkContentOffsetXForCiruclarCarouselLogic(scrollView) | |
} | |
} | |
private func checkContentOffsetXForCiruclarCarouselLogic(scrollView: UIScrollView) { | |
if(circularScrollingEnabled == true) { | |
var lastContentOffsetX: CGFloat = 0 | |
let currentOffsetX = scrollView.contentOffset.x | |
let currentOffsetY = scrollView.contentOffset.y | |
let pageWidth = scrollView.frame.size.width | |
let offset = pageWidth * CGFloat(self.polls.count - 2) | |
if(currentOffsetX < pageWidth && lastContentOffsetX > currentOffsetX) { | |
lastContentOffsetX = currentOffsetX + offset | |
scrollView.contentOffset = CGPoint(x: lastContentOffsetX, y: currentOffsetY) | |
} else if(currentOffsetX > offset && lastContentOffsetX < currentOffsetX) { | |
lastContentOffsetX = currentOffsetX - offset | |
scrollView.contentOffset = CGPoint(x: lastContentOffsetX, y: currentOffsetY) | |
} else { | |
lastContentOffsetX = currentOffsetX | |
} | |
} | |
} | |
private func checkPage(scrollView: UIScrollView) { | |
let pageWidth = scrollView.frame.size.width | |
let currentPageFloat = scrollView.contentOffset.x / pageWidth | |
if(circularScrollingEnabled == false) { | |
self.pageControl.currentPage = Int(round(currentPageFloat)) | |
} else { | |
let currentPageInt = Int(round(currentPageFloat - 1)) | |
if(currentPageInt >= 0) { | |
if(self.pageControl != nil) { | |
self.pageControl.currentPage = currentPageInt | |
} | |
} else { | |
if(self.pageControl != nil) { | |
self.pageControl.currentPage = self.polls.count - 3 | |
} | |
} | |
} | |
} | |
override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int { | |
return 1 | |
} | |
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { | |
return self.polls.count | |
} | |
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { | |
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("carouselCell", forIndexPath: indexPath) as! PollCollectionViewCell | |
//cell.delegate = self | |
let poll = self.polls[indexPath.row] | |
cell.updateView(poll) | |
return cell | |
} | |
} | |
extension PollCollectionViewController: PollCollectionViewCellDelegate { | |
func dummyFunc(info: String) { | |
log.debug(info) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment