lessons learned. swift - d2wakvpiukf49j.cloudfront.net · swift mix of good practices from multiple...
TRANSCRIPT
![Page 1: LESSONS LEARNED. SWIFT - d2wakvpiukf49j.cloudfront.net · SWIFT mix of good practices from multiple languages, rooted in C, statically typed language, no nil as we know it, let n](https://reader030.vdocument.in/reader030/viewer/2022040418/5dd0ceedd6be591ccb62cc9e/html5/thumbnails/1.jpg)
LESSONS LEARNED. SWIFTDagna Bieda, 7th April 2016
![Page 2: LESSONS LEARNED. SWIFT - d2wakvpiukf49j.cloudfront.net · SWIFT mix of good practices from multiple languages, rooted in C, statically typed language, no nil as we know it, let n](https://reader030.vdocument.in/reader030/viewer/2022040418/5dd0ceedd6be591ccb62cc9e/html5/thumbnails/2.jpg)
SWIFT & XCODEBrief Intro
![Page 3: LESSONS LEARNED. SWIFT - d2wakvpiukf49j.cloudfront.net · SWIFT mix of good practices from multiple languages, rooted in C, statically typed language, no nil as we know it, let n](https://reader030.vdocument.in/reader030/viewer/2022040418/5dd0ceedd6be591ccb62cc9e/html5/thumbnails/3.jpg)
“ Language that essentially marries the readability of Python with the speed of C++.
@jeremyconkin
![Page 4: LESSONS LEARNED. SWIFT - d2wakvpiukf49j.cloudfront.net · SWIFT mix of good practices from multiple languages, rooted in C, statically typed language, no nil as we know it, let n](https://reader030.vdocument.in/reader030/viewer/2022040418/5dd0ceedd6be591ccb62cc9e/html5/thumbnails/4.jpg)
SWIFT
➤ mix of good practices from multiple languages, rooted in C,
➤ statically typed language,
➤ no nil as we know it, let n = nil // type of expression is ambiguous without more context
let i : Int? = nil // the result is actually Optional<Int>.None
➤ all variables must be initialized before using them,
➤ memory management done by Automatic Reference Counting,
➤ object-oriented, functional, generic, protocol-oriented,
![Page 5: LESSONS LEARNED. SWIFT - d2wakvpiukf49j.cloudfront.net · SWIFT mix of good practices from multiple languages, rooted in C, statically typed language, no nil as we know it, let n](https://reader030.vdocument.in/reader030/viewer/2022040418/5dd0ceedd6be591ccb62cc9e/html5/thumbnails/5.jpg)
SWIFT
➤ very large community,
➤ massive amount of free tutorials (www.raywenderlich.com),
➤ recently open-sourced,
➤ possible to create server backend using Kitura-IBM or Perfect
![Page 6: LESSONS LEARNED. SWIFT - d2wakvpiukf49j.cloudfront.net · SWIFT mix of good practices from multiple languages, rooted in C, statically typed language, no nil as we know it, let n](https://reader030.vdocument.in/reader030/viewer/2022040418/5dd0ceedd6be591ccb62cc9e/html5/thumbnails/6.jpg)
SWIFT. WHERE TO LEARN FROM
➤ stackoverflow.com
➤ youtube.com: Stanford - Developing iOS 8 Apps with Swift
➤ udacity.com:
A. Intro to iOS App Development with Swift
B. iOS Developer Nanodegree
➤ edx.com
➤ coursera.com
![Page 7: LESSONS LEARNED. SWIFT - d2wakvpiukf49j.cloudfront.net · SWIFT mix of good practices from multiple languages, rooted in C, statically typed language, no nil as we know it, let n](https://reader030.vdocument.in/reader030/viewer/2022040418/5dd0ceedd6be591ccb62cc9e/html5/thumbnails/7.jpg)
XCODE
➤ enforces type-safety, // var was never changed, consider changing to let
➤ integrated with control management systems - git and SVN,
➤ code coverage, profiling, memory usage, leaks,
➤ test recording,
➤ storyboards <3
![Page 8: LESSONS LEARNED. SWIFT - d2wakvpiukf49j.cloudfront.net · SWIFT mix of good practices from multiple languages, rooted in C, statically typed language, no nil as we know it, let n](https://reader030.vdocument.in/reader030/viewer/2022040418/5dd0ceedd6be591ccb62cc9e/html5/thumbnails/8.jpg)
HEALTH CAREapp case study
![Page 9: LESSONS LEARNED. SWIFT - d2wakvpiukf49j.cloudfront.net · SWIFT mix of good practices from multiple languages, rooted in C, statically typed language, no nil as we know it, let n](https://reader030.vdocument.in/reader030/viewer/2022040418/5dd0ceedd6be591ccb62cc9e/html5/thumbnails/9.jpg)
APP REQUIREMENTS
➤ Facilitate communication between patient and their nurse,
➤ Share health data of the patient on a daily basis,
➤ Share videos and/or documents,
➤ Simple management of multiple patients,
➤ Be easy to use (non tech-savvy users)
![Page 10: LESSONS LEARNED. SWIFT - d2wakvpiukf49j.cloudfront.net · SWIFT mix of good practices from multiple languages, rooted in C, statically typed language, no nil as we know it, let n](https://reader030.vdocument.in/reader030/viewer/2022040418/5dd0ceedd6be591ccb62cc9e/html5/thumbnails/10.jpg)
DEMO APP + TEST
![Page 11: LESSONS LEARNED. SWIFT - d2wakvpiukf49j.cloudfront.net · SWIFT mix of good practices from multiple languages, rooted in C, statically typed language, no nil as we know it, let n](https://reader030.vdocument.in/reader030/viewer/2022040418/5dd0ceedd6be591ccb62cc9e/html5/thumbnails/11.jpg)
CODE EXAMPLESimport GRDB
enum UserType: String, DatabaseValueConvertible { case Nurse = "Nurse", Patient = "Patient"
var databaseValue: DatabaseValue { get { return DatabaseValue(object: self.rawValue)! } }
static func fromDatabaseValue(databaseValue: DatabaseValue) -> UserType? { let value = databaseValue.value() as! String return UserType(rawValue: value) }
func toggled() -> UserType { switch self{ case .Nurse : return .Patient case .Patient : return .Nurse } } }
![Page 12: LESSONS LEARNED. SWIFT - d2wakvpiukf49j.cloudfront.net · SWIFT mix of good practices from multiple languages, rooted in C, statically typed language, no nil as we know it, let n](https://reader030.vdocument.in/reader030/viewer/2022040418/5dd0ceedd6be591ccb62cc9e/html5/thumbnails/12.jpg)
CODE EXAMPLESprotocol DashboardDrawable { func setupAt(origin: CGPoint, xOffset: CGFloat, size: CGSize, addToView masterView: UIScrollView) }
class MessageView: UIView, DashboardDrawable {
func setupAt(origin: CGPoint, xOffset: CGFloat, size: CGSize, addToView masterView: UIScrollView){ var frame = CGRect(origin: origin, size: size) frame.origin.x += xOffset self.frame = frame self.backgroundColor = UserSettings.messageViewColor self.addLabels() masterView.addSubview(self) } }
![Page 13: LESSONS LEARNED. SWIFT - d2wakvpiukf49j.cloudfront.net · SWIFT mix of good practices from multiple languages, rooted in C, statically typed language, no nil as we know it, let n](https://reader030.vdocument.in/reader030/viewer/2022040418/5dd0ceedd6be591ccb62cc9e/html5/thumbnails/13.jpg)
CODE EXAMPLESprotocol DashboardDrawable { func setupAt(origin: CGPoint, xOffset: CGFloat, size: CGSize, addToView masterView: UIScrollView) }
class MessageView: UIView, DashboardDrawable {
func setupAt(origin: CGPoint, xOffset: CGFloat, size: CGSize, addToView masterView: UIScrollView){ var frame = CGRect(origin: origin, size: size) frame.origin.x += xOffset self.frame = frame self.backgroundColor = UserSettings.messageViewColor self.addLabels() masterView.addSubview(self) } }
// Usage in DashboardDetailTableViewController private func preparePatientDataForCell(cell: PatientDataCell, patient: Patient, date: NSDate, viewSize: CGSize) {
let width = computeDashboardsElementWidth(viewSize.width) let size = CGSize(width: width, height: viewSize.height)
let matchPatientsIdAndSelectedDate = { (cp: ContactPointProtocol) -> Bool in return cp.patientId == patient.serverId && cp.date ~= date }
for message in dbWrapper.messages.filter(matchPatientsIdAndSelectedDate) { let view = MessageView(message: message)
let offset = timeline.calculateDateOffset(message.date) view.setupAt(CGPointZero, xOffset: offset, size: size, addToView: cell.patientDashboard) } }
![Page 14: LESSONS LEARNED. SWIFT - d2wakvpiukf49j.cloudfront.net · SWIFT mix of good practices from multiple languages, rooted in C, statically typed language, no nil as we know it, let n](https://reader030.vdocument.in/reader030/viewer/2022040418/5dd0ceedd6be591ccb62cc9e/html5/thumbnails/14.jpg)
CODE EXAMPLESprotocol DateDisplayButtonDelegate: class { func dateDidChange(newDate: NSDate) }
class DateDisplayButton: UIButton {
var date: NSDate! { // ! deferred initialization didSet{ if oldValue != date { let components = NSCalendar.currentCalendar().components([.Month, .Day, .Weekday], fromDate: date) let weekday = Weekday(rawValue: components.weekday)!.description let month = Month(rawValue: components.month)!.description let day = components.day let title = String("\(weekday), \(month) \(day)") self.setTitle(title, forState: .Normal)
if oldValue != nil { delegate?.dateDidChange(date) } } } } var delegate: DateDisplayButtonDelegate? }
! ?
![Page 15: LESSONS LEARNED. SWIFT - d2wakvpiukf49j.cloudfront.net · SWIFT mix of good practices from multiple languages, rooted in C, statically typed language, no nil as we know it, let n](https://reader030.vdocument.in/reader030/viewer/2022040418/5dd0ceedd6be591ccb62cc9e/html5/thumbnails/15.jpg)
CODE EXAMPLESprotocol DateDisplayButtonDelegate: class { func dateDidChange(newDate: NSDate) }
class DateDisplayButton: UIButton {
var date: NSDate! { didSet{ if oldValue != date { \\ ... if oldValue != nil { delegate?.dateDidChange(date) } } } } var delegate: DateDisplayButtonDelegate? }
class DashboardDetailTableViewController: UIViewController, UITableViewDelegate, UIScrollViewDelegate, UIPopoverDelegate, DateDisplayButtonDelegate {
@IBOutlet weak var dateDisplayButton: DateDisplayButton! { didSet { dateDisplayButton.delegate = self } }
// MARK: DateDisplayButtonDelegate func dateDidChange(newDate: NSDate) { preparePatientsData(newDate) } }
![Page 16: LESSONS LEARNED. SWIFT - d2wakvpiukf49j.cloudfront.net · SWIFT mix of good practices from multiple languages, rooted in C, statically typed language, no nil as we know it, let n](https://reader030.vdocument.in/reader030/viewer/2022040418/5dd0ceedd6be591ccb62cc9e/html5/thumbnails/16.jpg)
CODE EXAMPLESprivate extension UIColor { class var random: UIColor { switch arc4random()%5 { case 0: return UIColor.greenColor() case 1: return UIColor.blueColor() case 2: return UIColor.orangeColor() case 3: return UIColor.redColor() case 4: return UIColor.purpleColor() default: return UIColor.blackColor() } } }
// Tuples and _ placeholder class TimelineDashboardHeader: UIScrollView { var majorTics = [NSDate : (String, (UILabel, UIBezierPath))]() var minorTics = [NSDate : (String, UIBezierPath)]()
func calculateDateOffset(date: NSDate) -> CGFloat{ let roundedDate = roundedDownToNearestHalfHour(date)
var tic: UIBezierPath? = UIBezierPath() if let (_, (_ , tic)) = majorTics[roundedDate] { let roundedX = tic.currentPoint.x let timeDistance = CGFloat(date.timeIntervalSinceNow - roundedDate.timeIntervalSinceNow) let xOffset = roundedX + (timeDistance/majorTicsTimespan * intervalSize) return xOffset } else { return 0.0 }
}
![Page 17: LESSONS LEARNED. SWIFT - d2wakvpiukf49j.cloudfront.net · SWIFT mix of good practices from multiple languages, rooted in C, statically typed language, no nil as we know it, let n](https://reader030.vdocument.in/reader030/viewer/2022040418/5dd0ceedd6be591ccb62cc9e/html5/thumbnails/17.jpg)
NOT SO FUN PART➤ casting Int or Double to CGFloat
func frameForMenuButton(indexPath: NSIndexPath) -> CGRect { let row = indexPath.row / numberOfColumns let column = indexPath.row % numberOfColumns
let originX: CGFloat = floor((itemSize.width + horizontalSpace) * CGFloat(column)) let originY: CGFloat = floor((itemSize.height + verticalSpace) * CGFloat(row))
return CGRectMake(originX, originY, itemSize.width, itemSize.height) }
➤ mysterious UIScrollView ➤ “in” to denote end of a closure’s type signature ➤ protocol with a settable variable has to be restricted to classes (it not a struct with a mutating setter which should be allowed)
![Page 18: LESSONS LEARNED. SWIFT - d2wakvpiukf49j.cloudfront.net · SWIFT mix of good practices from multiple languages, rooted in C, statically typed language, no nil as we know it, let n](https://reader030.vdocument.in/reader030/viewer/2022040418/5dd0ceedd6be591ccb62cc9e/html5/thumbnails/18.jpg)
THANK YOU!
#ifdef greatPresentation
#include ”standing-ovation.hpp”
#endif