Skip to content

Commit

Permalink
Xcode 6.3 Beta 2 updates
Browse files Browse the repository at this point in the history
  • Loading branch information
jpsim committed Mar 2, 2015
1 parent c3760a0 commit 8eac8a3
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 65 deletions.
16 changes: 9 additions & 7 deletions OSX/DeckRocket/MultipeerClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import MultipeerConnectivity

typealias stateChange = ((state: MCSessionState) -> ())?
private typealias KVOContext = UInt8
private var ProgressContext = KVOContext()
private var progressContext = KVOContext()
private var lastDisplayTime = NSDate()

final class MultipeerClient: NSObject, MCNearbyServiceAdvertiserDelegate, MCSessionDelegate {

Expand Down Expand Up @@ -45,15 +46,15 @@ final class MultipeerClient: NSObject, MCNearbyServiceAdvertiserDelegate, MCSess
if let peer = session?.connectedPeers[0] as? MCPeerID {
pdfProgress = session?.sendResourceAtURL(url, withName: filePath.lastPathComponent, toPeer: peer) { error in
dispatch_async(dispatch_get_main_queue()) {
self.pdfProgress?.removeObserver(self, forKeyPath: "fractionCompleted", context: &ProgressContext)
self.pdfProgress?.removeObserver(self, forKeyPath: "fractionCompleted", context: &progressContext)
if let errorDescription = error?.localizedDescription {
HUDView.show("Error!\n\(errorDescription)")
} else {
HUDView.show("Success!")
}
}
}
pdfProgress?.addObserver(self, forKeyPath: "fractionCompleted", options: .New, context: &ProgressContext)
pdfProgress?.addObserver(self, forKeyPath: "fractionCompleted", options: .New, context: &progressContext)
}
}

Expand Down Expand Up @@ -96,14 +97,15 @@ final class MultipeerClient: NSObject, MCNearbyServiceAdvertiserDelegate, MCSess
// MARK: KVO

override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<()>) {
if context == &ProgressContext {
dispatch_async(dispatch_get_main_queue()) {
if context != &progressContext {
super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
} else if abs(lastDisplayTime.timeIntervalSinceNow) > 1/60 { // Update HUD at no more than 60fps
dispatch_sync(dispatch_get_main_queue()) {
if let progress = change[NSKeyValueChangeNewKey] as? CGFloat {
HUDView.showProgress(progress, string: "Sending File to iPhone")
lastDisplayTime = NSDate()
}
}
} else {
super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
}
}
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

## Requirements

DeckRocket is built in Swift and relies on Multipeer Connectivity on both OSX and iOS. Xcode 6.3b, OS X 10.10 and iOS 8 are all required to build, install and use DeckRocket.
DeckRocket is built in Swift and relies on Multipeer Connectivity on both OSX and iOS. Xcode 6.3b2, OS X 10.10 and iOS 8 are all required to build, install and use DeckRocket.

## Usage

Expand Down
56 changes: 23 additions & 33 deletions iOS/DeckRocket/MultipeerClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ final class MultipeerClient: NSObject, MCNearbyServiceBrowserDelegate, MCSession
// MARK: Send

func send(data: NSData) {
if let session = session {
session.sendData(data, toPeers: session.connectedPeers, withMode: .Reliable, error: nil)
}
session?.sendData(data, toPeers: session!.connectedPeers, withMode: .Reliable, error: nil) // Safe to force unwrap
}

func sendString(string: NSString) {
Expand Down Expand Up @@ -79,32 +77,25 @@ final class MultipeerClient: NSObject, MCNearbyServiceBrowserDelegate, MCSession

func session(session: MCSession!, didFinishReceivingResourceWithName resourceName: String!, fromPeer peerID: MCPeerID!, atURL localURL: NSURL!, withError error: NSError!) {
if error == nil {
// FIXME: Switch on FileType once it works
// TODO: File radar for this
if contains(FileType.extensionsForType(.PDF), resourceName.pathExtension) {
handlePDF(resourceName, atURL: localURL)
} else if contains(FileType.extensionsForType(.Markdown), resourceName.pathExtension) {
handleMarkdown(resourceName, atURL: localURL)
if let fileType = FileType(fileExtension: resourceName.pathExtension) {
switch fileType {
case .PDF:
handlePDF(resourceName, atURL: localURL)
case .Markdown:
handleMarkdown(resourceName, atURL: localURL)
}
}
// if let fileType = FileType(fileExtension: resourceName.pathExtension) {
// switch fileType {
// case .PDF:
// handlePDF(resourceName, atURL: localURL)
// case .Markdown:
// handleMarkdown(resourceName, atURL: localURL)
// }
// }
}
}

// MARK: Handle Resources

private func handlePDF(resourceName: String!, atURL localURL: NSURL!) {
promptToLoadResource("New Presentation File", resourceName: resourceName, atURL: localURL, userDefaultsKey: "pdfPath")
promptToLoadResource("New Presentation File", resourceName: resourceName, atURL: localURL, userDefaultsKey: "pdfName")
}

private func handleMarkdown(resourceName: String!, atURL localURL: NSURL!) {
promptToLoadResource("New Markdown File", resourceName: resourceName, atURL: localURL, userDefaultsKey: "mdPath")
promptToLoadResource("New Markdown File", resourceName: resourceName, atURL: localURL, userDefaultsKey: "mdName")
}

private func promptToLoadResource(title: String, resourceName: String, atURL localURL: NSURL, userDefaultsKey: String) {
Expand All @@ -113,22 +104,21 @@ final class MultipeerClient: NSObject, MCNearbyServiceBrowserDelegate, MCSession
let alert = UIAlertController(title: title, message: "Would you like to load \"\(resourceName)\"?", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
alert.addAction(UIAlertAction(title: "Load", style: .Default) { action in
if let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as? NSString {
let filePath = documentsPath.stringByAppendingPathComponent(resourceName)
let filePath = documentsPath.stringByAppendingPathComponent(resourceName)
let fileManager = NSFileManager.defaultManager()

var error: NSError? = nil
if NSFileManager.defaultManager().fileExistsAtPath(filePath) {
NSFileManager.defaultManager().removeItemAtPath(filePath, error: &error)
}
var error: NSError? = nil
if fileManager.fileExistsAtPath(filePath) {
fileManager.removeItemAtPath(filePath, error: &error)
}

if let url = NSURL(fileURLWithPath: filePath) {
NSFileManager.defaultManager().moveItemAtURL(localURL, toURL: url, error: &error)
if error == nil {
NSUserDefaults.standardUserDefaults().setObject(filePath, forKey: userDefaultsKey)
NSUserDefaults.standardUserDefaults().synchronize()
rootVC?.updatePresentation()
}
}
if let url = NSURL(fileURLWithPath: filePath) where fileManager.moveItemAtURL(localURL, toURL: url, error: &error) {
NSUserDefaults.standardUserDefaults().setObject(resourceName, forKey: userDefaultsKey)
NSUserDefaults.standardUserDefaults().synchronize()
rootVC?.updatePresentation()
} else {
let message = error?.localizedDescription ?? "move file failed with no error"
fatalError(message)
}
})
dispatch_async(dispatch_get_main_queue()) {
Expand Down
12 changes: 6 additions & 6 deletions iOS/DeckRocket/PDFImages.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import CoreGraphics

extension UIImage {
static func imagesFromPDFPath(pdfPath: String) -> [UIImage] {
if let pdfURL = NSURL(fileURLWithPath: pdfPath) {
let pdf = CGPDFDocumentCreateWithURL(pdfURL)
if let pdfURL = NSURL(fileURLWithPath: pdfPath),
let pdf = CGPDFDocumentCreateWithURL(pdfURL) {
let numberOfPages = CGPDFDocumentGetNumberOfPages(pdf)

if numberOfPages == 0 {
Expand All @@ -25,7 +25,7 @@ extension UIImage {
let largestDimension = max(screenSize.width, screenSize.height)
let largestSize = CGSize(width: largestDimension, height: largestDimension)

for pageNumber in 1...numberOfPages {
for pageNumber in 1...Int(numberOfPages) {
if let image = UIImage(pdfURL: pdfURL, page: pageNumber, fitSize: largestSize) {
images.append(image)
}
Expand All @@ -36,13 +36,13 @@ extension UIImage {
return []
}

private static func pdfRectForURL(url: NSURL, page: UInt) -> CGRect {
private static func pdfRectForURL(url: NSURL, page: Int) -> CGRect {
let pdf = CGPDFDocumentCreateWithURL(url)
let pageRef = CGPDFDocumentGetPage(pdf, page)
return CGPDFPageGetBoxRect(pageRef, kCGPDFCropBox)
}

convenience init?(pdfURL: NSURL, page: UInt, size: CGSize) {
convenience init?(pdfURL: NSURL, page: Int, size: CGSize) {
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.mainScreen().scale)

let ctx = UIGraphicsGetCurrentContext()
Expand All @@ -66,7 +66,7 @@ extension UIImage {
self.init(CGImage: pdfImage.CGImage)
}

convenience init?(pdfURL: NSURL, page: UInt, fitSize size: CGSize) {
convenience init?(pdfURL: NSURL, page: Int, fitSize size: CGSize) {
let rect = UIImage.pdfRectForURL(pdfURL, page: page)
let scaleFactor = max(rect.size.width / size.width, rect.size.height / size.height)
let newWidth = ceil(rect.size.width / scaleFactor)
Expand Down
54 changes: 36 additions & 18 deletions iOS/DeckRocket/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,27 @@
import UIKit
import MultipeerConnectivity

let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as! NSString

private func userDefaultsString(key: String) -> String? {
return NSUserDefaults.standardUserDefaults().objectForKey(key) as? NSString as? String
}

private func userDefaultsPathIfFileExists(key: String) -> String? {
if let name = userDefaultsString(key), let path = Optional(documentsPath.stringByAppendingPathComponent(name)) where NSFileManager.defaultManager().fileExistsAtPath(path) {
return path
}
return nil
}

final class ViewController: UICollectionViewController, UIScrollViewDelegate {

// MARK: Properties

private var presentation: Presentation?
private let multipeerClient = MultipeerClient()
// UIVisualEffectView's alpha can't be animated, so we nest it in a parent view
private let effectParentView = UIView()
private let effectView = UIVisualEffectView(effect: UIBlurEffect(style: .Dark))
private let notesView = UITextView()
private let nextSlideView = UIImageView()
Expand Down Expand Up @@ -52,23 +63,23 @@ final class ViewController: UICollectionViewController, UIScrollViewDelegate {
switch state {
case .NotConnected:
if self.multipeerClient.session == nil {
self.effectView.alpha = 1
self.effectParentView.alpha = 1
self.infoLabel.text = "Not Connected"
} else if self.multipeerClient.session!.connectedPeers.count == 0 { // Safe to force unwrap
self.effectView.alpha = 1
self.effectParentView.alpha = 1
self.infoLabel.text = "Not Connected"
self.multipeerClient.browser?.invitePeer(peerID, toSession: self.multipeerClient.session, withContext: nil, timeout: 30)
}
case .Connected:
if let presentation = self.presentation {
self.effectView.alpha = 0
self.effectParentView.alpha = 0
self.infoLabel.text = ""
} else {
self.effectView.alpha = 1
self.effectParentView.alpha = 1
self.infoLabel.text = "No Presentation Loaded"
}
case .Connecting:
self.effectView.alpha = 1
self.effectParentView.alpha = 1
self.infoLabel.text = "Connecting..."
}
})
Expand All @@ -78,9 +89,9 @@ final class ViewController: UICollectionViewController, UIScrollViewDelegate {
// MARK: Presentation Updates

func updatePresentation() {
if let pdfPath = userDefaultsString("pdfPath") {
if let pdfPath = userDefaultsPathIfFileExists("pdfName") {
let markdown: String?
if let mdPath = userDefaultsString("mdPath") {
if let mdPath = userDefaultsPathIfFileExists("mdName") {
markdown = String(contentsOfFile: mdPath, encoding: NSUTF8StringEncoding)
} else {
markdown = nil
Expand Down Expand Up @@ -111,13 +122,21 @@ final class ViewController: UICollectionViewController, UIScrollViewDelegate {
}

private func setupEffectView() {
effectView.setTranslatesAutoresizingMaskIntoConstraints(false)
view.addSubview(effectView)
effectParentView.setTranslatesAutoresizingMaskIntoConstraints(false)
view.addSubview(effectParentView)

let horizontal = NSLayoutConstraint.constraintsWithVisualFormat("|[effectView]|", options: nil, metrics: nil, views: ["effectView": effectView])
let vertical = NSLayoutConstraint.constraintsWithVisualFormat("V:|[effectView]|", options: nil, metrics: nil, views: ["effectView": effectView])
let horizontal = NSLayoutConstraint.constraintsWithVisualFormat("|[effectParentView]|", options: nil, metrics: nil, views: ["effectParentView": effectParentView])
let vertical = NSLayoutConstraint.constraintsWithVisualFormat("V:|[effectParentView]|", options: nil, metrics: nil, views: ["effectParentView": effectParentView])
view.addConstraints(horizontal)
view.addConstraints(vertical)

effectView.setTranslatesAutoresizingMaskIntoConstraints(false)
effectParentView.addSubview(effectView)

let horizontal2 = NSLayoutConstraint.constraintsWithVisualFormat("|[effectView]|", options: nil, metrics: nil, views: ["effectView": effectView])
let vertical2 = NSLayoutConstraint.constraintsWithVisualFormat("V:|[effectView]|", options: nil, metrics: nil, views: ["effectView": effectView])
effectParentView.addConstraints(horizontal2)
effectParentView.addConstraints(vertical2)
}

private func setupInfoLabel() {
Expand Down Expand Up @@ -213,10 +232,8 @@ final class ViewController: UICollectionViewController, UIScrollViewDelegate {
break
default:
// Don't do anything if the effect view is now being used to show a connectivity message
if let session = multipeerClient.session {
if session.connectedPeers.count > 0 {
showNotes(false)
}
if let session = multipeerClient.session where session.connectedPeers.count > 0 {
showNotes(false)
}
}
}
Expand All @@ -233,11 +250,12 @@ final class ViewController: UICollectionViewController, UIScrollViewDelegate {
} else {
nextSlideView.image = nil
}
let alpha = CGFloat(show)
UIView.animateWithDuration(0.25, animations: {
self.effectView.alpha = CGFloat(show)
self.effectParentView.alpha = alpha
}) { finished in
self.notesView.alpha = CGFloat(show)
self.nextSlideView.alpha = CGFloat(show)
self.notesView.alpha = alpha
self.nextSlideView.alpha = alpha
}
}
}
Expand Down

0 comments on commit 8eac8a3

Please sign in to comment.