안녕하세요 오랜만에 개발 관련 글을 적게 됩니다. 몇 안되지만, 그동안 애자일 개발 프로세스를 사용했던 프로젝트 참여 경험과 호주 유학 시절 접했던 소프트웨어 개발 교육 내용을 토대로 적어 내려가며 최근 자료로 업데이트도 하고, 정리도 하며 공유 해 보려고 합니다. 

2018년 현재, 국내에서 Agile (이하 애자일) 개발 프로세스 를 처음 듣는 개발자나 관리자는 거의 없을 것이라 생각됩니다. (경험하지않은 분들은 당연히 있을것입니다.) 꽤 오랬동안 Hot 한 방법론(프로세스) 이였고, 여러 방법으로 이 프로세스를 개발 문화로 안착 시키려고 상당히 많은 분들이 노력 해 오셨습니다. 그래서 많은, 성공설도, 실패설도 있습니다. 

개발 방법은 전통적인 방법인 워터폴도 있고, 스파이럴 혹은 프로토타이핑 방법 등이 있는데 왜 애자일 개발 방법론을 선택하여 개발 해야 할까요? 10년전 필드에서는 벌써 전통적인 워터폴의 문제점들을 보안하고 변형시킨, 애자일 혹은 DevOps (이하 데브옵스) 등의 단어들을 사용하지 않더라도, 오랜 경험을 바탕으로 필요에 의해 내부적으로 개발 프로세스를 애자일 식으로 자연스레 변경한 팀 (Team) 들이 있었습니다. 하지만 대부분 워터폴 방법으로 개발 했고, 윗단계에서 발생한 문제점들은, 폭포수가 단계적으로 내려오며 마지막에 엄청난 량의 물이 떨어지듯, 엄청난 량의 문제점들과 이를 수습하기 위한 엄청난 비용, 노력, 밤샘 등의 반복이 있었습니다. 

때문에, [12 Annual State of Agile Report] 조사에 의하면 2017년엔 조사한 대상 회사 중, 97% 나 되는 회사에서 애자일 개발 방법론을 채택 했을 정도로 많이 확산되어 있습니다. 참고로 조사 대상 중 80% 이상이 미국과 유럽내 있는 회사들입니다. 그리고 이 방법론이 더욱 효과적으로 사용 하기 위해 지속적인 변형이 일어나고 있습니다. Scrum [56%] 방법이 가장 많이 선택되고 실행 되고 있지만, 필요에 따라 Scrum/XP 하이브리드 [6%], 나 ScrumBan [8%], 등 현재 소개된 애자일 개발 방법론들의 하이브리드 형태로 받아들여지고 있습니다. 

그 어떤 형태로든 애자일 개발 방법을 선택하여 진행된 프로젝트 중 성공 비율은 [12 Annual State of Agile Report] 조사 대상 중 98% 회사에서 애자일 개발 방법을 선택한 프로젝트의 성공 경험이 있다고 답변을 했습니다. 그리고 이 중 74% 는 반 이상의 애자일 프로젝트가 성공적으로 끝났다고 합니다. 

프로젝트 성공의 잣대는 역시나 주어진 시간 내, 계획을 잘 세워, 예상한 비용 만큼만 사용하여 모든 Scope 을 완료 하였다 일까요? 애자일에서는 이터레이션 번다운이 이를 설명하는 가장 근사치의 요소일 텐데요. 2016년만 하더라고 51%의 답변으로 가장 중요한 요소를 차지 했었습니다.  하지만, 올해엔 27%로 중요도가 떨어졌습니다. 

그 이유는 애자일 프로젝트가 성공적이라고 결정하는 가장 큰 요소가 2017년엔, 첫번째는 고객 만족도 이고, 비지니스의 가치 전달, 그리고 개발 후 마켓으로의 속도 순으로 바뀌었기 때문입니다. 여기서 고객 만족도는 2016년만 해도 28% 정도의 순위였는데 2017년에는 46%로 가장 중요한 요소가 되었습니다.

경험상, 어떤 고객(사용자)이든, 작게 나마 완성되어 돌아가는 프로그램을 지속적으로 보여주면서, 피드백을 받아주는 개발팀을 싫어하는 고객은 없었습니다. 결과물들을 더 자주 보기 위해 1 week Sprint (스프린트) 를 돌렸던 프로젝트도 있었던 것처럼 고객은 결과물을 자주 보고 피드백을 주며 그 피드백들이 대부분 적용되었으면 합니다. 여기서 개발팀은 Scope 이 늘어나기 때문에 초기 요청사항에서 동떨어진 피드백을 받기를 당연히 원하지 않습니다. 하지만 이를 위해 스프린트 (이터레이션) 마다 Story Card 의 우선순위를 바꾸는 회의가 진행됩니다. 고객(사용자)은 비지니스와 불필요한 Needs 에 대해 고집을 부리지 않습니다. 물론 같은 비용으로 더 많은 부분이 완료 되었으면 하지만, 불필요한 부분으로 인하여 정말 주요기능들이 빠지는 것을 원하지 않습니다. 우선순위 회의의 결과를 공유하여 문제 파악과 해결점을 함께 찾아야 합니다. 

여하튼, 요구사항이 바뀌는 것을 최소화 하기 위해 애자일에서는 Product Owner (PO) 가 늘 함께 해야 한다..는 실제로 불가능한 이론을 이야기 합니다. 분명 PO 의 참여도가 떨어진다라는 요소가 2016년 까지는 큰 장벽 요소 중 하나였지만, 2017년엔 31%로 큰 장벽의 요소에서는 제외 되었습니다. 아마도, 스프린트 끝의 회의 때마다 PO 에게 사용해 보게 한 뒤, 피드백을 받아, 점진적으로 고객의 Needs 에 대등한 완성도 높은 제품으로 변해가는 과정을 함께 경험/공유 하다 보면, PO 는 매 회의 때를 고대하게 되지 않을까 싶네요.

이렇게 많은 회사에서 사용중이라고 발표도 하고, 고객의 만족도가 높은 결과물을 낼 수 있는, 그리고 또 꽤 높은 성공률을 자랑하는 애자일 개발 방법론..

과연, 개발 팀원들은 (PO/개발/UI/BA/테스터) 한번 애자일을 경험한 후에 이 프로세스에 만족하며 이후에도 프로젝트를 위해 또 애자일 프로세스를 선택하게 될지 궁금합니다. 개인적으로는 무척 좋아했습니다. 짧은 스토리 카드 하나하나 완료 시키는 재미도 있고, 고객의 피드백이 늘 추가 요구사항이나 변경으로 이어지는것이 아니라, 후반으로 갈 수록 높은 만족도로 이어지는 경우가 대부분이라서 일을 하면서도 뿌듯했습니다.  

그렇다면 애자일 경험이 없는, 현재 개발 프로세스의 체계가 잘 잡혀 있지 않은 상태에서는 어떤 선택이 가장 좋을까요?

============

4년전, 2014년, 호주에서는 애자일 개발 프로세스를 소프트웨어 개발 방법론으로 채택한, 많은 프로젝트 들이 진행 되고 있었는데요. 당시 런칭 했던 많은 서비스들 중 Pizza Mogul 이라는 재미난 서비스가 있었습니다. Domino Pizza 를 통해, 소비자들이 피자를 디자인(도우,토핑 등) 할 수 있으며, 디자인된 피자가 다른 소비자들에게 판매가 되면, 그 이익금의 일부를 피자를 만든 소비자가 가지고 가는 서비스 입니다. 

Project Management 수업을 들을 때, Pizza Mogul 의 개발 아웃소싱 시 프로젝트 메니저가 선택한 개발 방법론은 Agile 개발 방법론이였으며 관련하여 수업에서 Agile 개발 경험을 공유해 주었습니다. 유학을 위해 호주 가기 전에 참여했던 Agile 개발 방법론을 채택했던 프로젝트들과 그리 다르진 않아서 조금 다행스럽기도 했습니다. 

흥미로웠던 점은 프레젠테이션이 끝나고, 질문 시간에, 제가 "워터폴이나 다른 여러 개발 방법론이 있는데 구지 Agile 을 택한 이유가 있나요?" 라는 질문에 "회사를 들어갔을 때 부터 개발 문화가 Agile 이여서 채택? 했을 뿐이다. 다른 개발 방법론은 경험해 보지 않아서 모르겠다." 라고 답변을 들었습니다. 실은 제가 초기에 개발 방법론을 이해 하며 개발 했던것이 아니였기 때문에 좋고 나쁘다를 판단 할 수 있는 데이터가 모자라 물어본 질문이였는데 의외로 그냥 사내 개발 문화로 자연스럽게 받아들였다는 대답을 들어 "당연한 것을" 물어봤나 하는 생각도 들었네요.

또한 "요구사항이 바뀌거나 늘어났을 텐데, 그에 대해서 고객과 어떤 조율이 이루어 졌나요?" 라는 질문에 대해서는 "매번 우선순위를 정했고, 고객과 공유하여 서비스를 위해 꼭 필요한 기능들에 우선순위를 정하였고, 변경을 수용했다. Scope 이 늘어나면 시간과 비용이 추가적으로 발생하는 점에 대해서 먼저 고객과 상호 이해가 되어야 한다... (생략)" 

============



<to be Continued...>


posted by Sungyoup Han matrim


Swift is like Kotlin : http://nilhcem.com/swift-is-like-kotlin/

'초짜 IT보이 서바이벌 스토리 > iOS - swift' 카테고리의 다른 글

SWIFT vs KOTLIN  (0) 2017.10.31
[swift] code log, day 5  (0) 2017.09.27
[swift] code log, day 4  (0) 2017.09.26
[swift] code log, day 3  (0) 2017.09.25
[swift] code log, day 2  (0) 2017.09.24
[swift] code log, day 1  (0) 2017.09.22

posted by Sungyoup Han matrim

iBooks 의 SWIFT 4 를 통해 언어 공부 중입니다. 이때 사용된 책 속의 코드 및 연습문제 등의 코드 로그입니다.



아래 코드들은 Github 에서도 다운받을 수 있습니다.

SWIFT_Playground_Excersice: https://github.com/youp-han/SWIFT_Playground_Excersice


//------------------------------------------------------------

// 코드 로그 입니다.

// Day 5


do {

    let printerResponse = try send(job: 1440, toPrinter: "Gutenberg")

    print(printerResponse)

} catch PrinterError.onFire{

    print("I'll just put this over here, with the rest of the fire.")

} catch let printerError as PrinterError{

    print("Printer error: \(printerError).")

} catch {

    print(error)

}


//optional try (try?) will convert result to an optional.

//so if the function throws an error, the error is discarded and

// result is nil

let printerSuccess = try? send(job: 1884, toPrinter: "Mergenthaler")

let printerFailure = try? send(job: 1884, toPrinter: "Never Has Toner")


//defer


var fridgeIsOpen = false


let fridgeContent = ["milk", "eggs", "leftovers"]


func fridgeContains(_ food: String) -> Bool {

    fridgeIsOpen = true

    defer{

        fridgeIsOpen = false

    }

    

    let result = fridgeContent.contains(food)

    return result

}


fridgeContains("banana")

print(fridgeIsOpen)



//Generics

func makeArray<Item>(repeating item: Item, numberOfTimes: Int) -> [Item]{

    var result = [Item]()

    for _ in 0..<numberOfTimes {

        result.append(item)

    }

    return result

}

makeArray(repeating: "knock", numberOfTimes: 4)



enum OptionalValue<Wrapped>{

    case none

    case some(Wrapped)

}

var possibleInteger: OptionalValue<Int> = .none

print("possibleinteger = \(possibleInteger)")

possibleInteger = .some(100)

print("possibleinteger (100) = \(possibleInteger)")


func anyCommonElements<T: Sequence, U: Sequence> (_ lhs: T, _ rhs: U) -> Bool where T.Iterator.Element: Equatable, T.Itertor.Element == U.Iterator.Element{

    for lhsItem in lhs{

        for rhsItem in rhs{

            if lhsItem == rhsItem {

                return true

            }

        }

    }

    

    return false

}


anyCommonElements([1,2,3], [3])



'초짜 IT보이 서바이벌 스토리 > iOS - swift' 카테고리의 다른 글

SWIFT vs KOTLIN  (0) 2017.10.31
[swift] code log, day 5  (0) 2017.09.27
[swift] code log, day 4  (0) 2017.09.26
[swift] code log, day 3  (0) 2017.09.25
[swift] code log, day 2  (0) 2017.09.24
[swift] code log, day 1  (0) 2017.09.22

posted by Sungyoup Han matrim

iBooks 의 SWIFT 4 를 통해 언어 공부 중입니다. 이때 사용된 책 속의 코드 및 연습문제 등의 코드 로그입니다.



아래 코드들은 Github 에서도 다운받을 수 있습니다.

SWIFT_Playground_Excersice: https://github.com/youp-han/SWIFT_Playground_Excersice


//------------------------------------------------------------

// 코드 로그 입니다.

// Day 4

// Enumerationas and Structures

// Default 로 raw value 는 0 에서 시작하지만, 다음의 경우

// case ace = 1에서 시작함.


enum Rank: Int{

    case ace = 1

    case two, three, four, five, six, seven, eight, nine, ten

    case jack, queen, king

    func simpleDescription() -> String{

        switch self{

        case .ace:

            return "ace"

        case .jack:

            return "jack"

        case .queen:

            return "queen"

        case .king:

            return "king"

        default:

            return String(self.rawValue)

        }

    }

}


let ace = Rank.ace

let aceRawValue = ace.rawValue

let two = Rank.two

let twoRawValue = two.rawValue


if let convertedRank = Rank(rawValue:3) {

    let threeDescription = convertedRank.simpleDescription()

print(threeDescription)

}



//enum 2

enum Suit{

    case spades, hearts, diamonds, clubs

    func simpleDescription()->String{

        switch self{

        case .spades:

            return "spades"

        case .hearts:

            return "hearts"

        case .diamonds:

            return "diamonds"

        case .clubs:

            return "clubs"

        }

    }

    

    //experiment

    func color()->String{

        switch self{

        case .spades:

            return "black"

        case .clubs:

            return "black"

        default:

            return "red"

        }

    }

}


let hearts = Suit.hearts

let heartsDescription = hearts.simpleDescription()

let heartsColor = hearts.color()



// enum 3


enum ServerResponse {

    case result (String, String)

    case failure (String)

}


let success = ServerResponse.result("6:00 am", "8:09 pm")

let failure = ServerResponse.failure("Out of cheese")


switch success {

case let .result(sunrise, sunset):

    print("Sunrise is at\(sunrise) and sunset is at \(sunset).")

case let .failure(message):

    print("Failure... \(message)")

}


//struct

// struct vs class

// struct gets copied where classes are passed by reference


struct Card {

    var rank: Rank

    var suit: Suit

    func simpleDescription() -> String {

        return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"

    }

}

let threeOfSpades = Card(rank: .three, suit: .spades)

let threeOfSpedesDescription = threeOfSpades.simpleDescription()



//Protocals and Estensions

//Classes, enum and Structs can adopt protocols


protocol ExampleProtocol {

    var simpleDescription : String { get }

    mutating func adjust()

}


class SimpleClass: ExampleProtocol{

    var simpleDescription: String = "A very simple class"

    var anotherProperty: Int = 52342

    func adjust(){

        simpleDescription += " Now 100% adjusted"

    }

}


var a = SimpleClass()

a.adjust()

let aDescription = a.simpleDescription


struct SimpleStruture: ExampleProtocol {

    var simpleDescription: String = "A simple structure"

    mutating func adjust(){

        simpleDescription += " (adjusted)"

    }

}


var b = SimpleStruture()

b.adjust()

let bDescription = b.simpleDescription


// why mutating func in Structure?

// because, the structure is a value type where class is a reference type

// and to make changes in a function of the structure,

// the function should be mutable

// example


struct Rectangle {

    var height = 1

    var width = 1


    func area() -> Int{

        return height * width

    }

    

    mutating func scaleBy(value: Int) {

        width*=value

        height*=value

    }

}


var rect = Rectangle()

// let rect = Rectangle() will give errors for its a value type (immutable)

rect.area()

rect.scaleBy(value: 3)

rect.area()



// extension of protocol


extension Int: ExampleProtocol {

    var simpleDescription: String {

        return "the number \(self)"

    }

    

    mutating func adjust(){

        self += 42

    }

}


print (7.simpleDescription)


let protocolValue: ExampleProtocol = a

print(protocolValue.simpleDescription)

//print(protocolValue.anotherProperty)


//Error Handling

enum PrinterError: Error{

    case outOfPaper

    case noToner

    case onFire

}


func send(job: Int, toPrinter printerName: String) throws -> String{

    if printerName == "Never Has Toner" {

        throw PrinterError.noToner

    }

    return "Job Sent"

}


do{

    // the following statement throws no error

    // let printerResponse = try send(job: 1040, toPrinter: "Bi Sheng")

     let printerResponse = try send(job: 1040, toPrinter: "Never Has Toner")

    print(printerResponse)

}catch{

    print(error)

}


'초짜 IT보이 서바이벌 스토리 > iOS - swift' 카테고리의 다른 글

SWIFT vs KOTLIN  (0) 2017.10.31
[swift] code log, day 5  (0) 2017.09.27
[swift] code log, day 4  (0) 2017.09.26
[swift] code log, day 3  (0) 2017.09.25
[swift] code log, day 2  (0) 2017.09.24
[swift] code log, day 1  (0) 2017.09.22

posted by Sungyoup Han matrim

iBooks 의 SWIFT 4 를 통해 언어 공부 중입니다. 이때 사용된 책 속의 코드 및 연습문제 등의 코드 로그입니다.



아래 코드들은 Github 에서도 다운받을 수 있습니다.

SWIFT_Playground_Excersice: https://github.com/youp-han/SWIFT_Playground_Excersice


//------------------------------------------------------------

// 코드 로그 입니다.

// Day 3


//Objects and Classes


class Shape{

    var numberOfSides = 0

    func simpleDescription() -> String {

        return "A shape with \(numberOfSides) sides."

    }


}




var shape = Shape()

shape.numberOfSides = 7

var shapeDescription = shape.simpleDescription();

print(shapeDescription)




//initializer

//when Initializing the class, the init variables must be declared

class NamedShape {

    var numberOfSides : Int = 0

    var name: String

    

    init(name: String){

        self.name = name

    }

    

    func simpleDescription() -> String{

        return "A Share with\(numberOfSides) sides, and the name is \(name)"

    }

}

var testname = NamedShape(name:"Mike")

print(testname.simpleDescription())



//superclass inherritance

class Square: NamedShape{

    var sideLength: Double

    init(sideLength: Double, name: String){

        self.sideLength = sideLength

        super.init(name: name)

        numberOfSides = 4

    }

    

    func area() -> Double {

        return sideLength * sideLength

    }

    

    override func simpleDescription() -> String {

        return "A square with sides of lengh \(sideLength)"

    }

}


let test = Square(sideLength: 5.2, name: "my Test Square")

print(test.area())

print(test.numberOfSides)

print(test.simpleDescription())



//excercise : area of Circle

class Circle: NamedShape{

    var radius: Double

    let pi: Double = 3.141592

    init(radius: Double, name: String){

        self.radius = radius

        super.init(name:name)

        numberOfSides = 0

    }

    

    func area() -> Double{

        return radius * radius * pi

    }

    

    override func simpleDescription() -> String {

        return "A circle with radius of \(radius)"

    }

}


var testCircle = Circle(radius: 4.0, name: "my Test Circle")

print(testCircle.area())

print(testCircle.simpleDescription())



//getter, setter of properties


class EquilateralTriangle: NamedShape{

    var sideLength: Double = 0.0

    

    init(sideLength: Double, name: String){

        self.sideLength = sideLength

        super.init(name: name)

        numberOfSides = 3

    }

    

    var perimeter: Double{

        get{

            return 3.0 * sideLength

        }

        set{

            sideLength = newValue / 3.0

        }

    }

    

    override func simpleDescription() -> String {

        return "An equilateral triangle with sides of length\(sideLength)"

    }

}


var triagle = EquilateralTriangle(sideLength: 3.1, name: "a Triagle")

print(triagle.perimeter)

triagle.perimeter = 9.9

print(triagle.sideLength)


class TriangleAndSquare{

    

    var triangle:EquilateralTriangle{

        willSet{

            square.sideLength = newValue.sideLength

        }

    }

    

    var square: Square{

        willSet{

            triagle.sideLength = newValue.sideLength

        }

    }

    

    init(size: Double, name: String){

        square = Square(sideLength: size, name: name)

        triangle = EquilateralTriangle(sideLength: size, name: name)

    }

}


var triangleAndSquare = TriangleAndSquare(size: 10, name: "Another Test Shape")

print(triangleAndSquare.square.sideLength)

print(triangleAndSquare.triangle.sideLength)

triangleAndSquare.square = Square(sideLength: 50, name: "Larger Square")

print(triangleAndSquare.triangle.sideLength)

print(triangleAndSquare.square.sideLength)



let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional Square")

let sideLength = optionalSquare?.sideLength

print("optional sidelength = \(sideLength)")


'초짜 IT보이 서바이벌 스토리 > iOS - swift' 카테고리의 다른 글

[swift] code log, day 5  (0) 2017.09.27
[swift] code log, day 4  (0) 2017.09.26
[swift] code log, day 3  (0) 2017.09.25
[swift] code log, day 2  (0) 2017.09.24
[swift] code log, day 1  (0) 2017.09.22
[swift] #SWIFT #4 언어 가이드  (0) 2017.09.22

posted by Sungyoup Han matrim


iBooks 의 SWIFT 4 를 통해 언어 공부 중입니다. 이때 사용된 책 속의 코드 및 연습문제 등의 코드 로그입니다.



아래 코드들은 Github 에서도 다운받을 수 있습니다.

SWIFT_Playground_Excersice: https://github.com/youp-han/SWIFT_Playground_Excersice


//------------------------------------------------------------

// 코드 로그 입니다.

// Day 2


//Function in Function (Closure)

func makeIncrementer() -> ((Int)-> Int) {

    func addOne (number: Int) -> Int {

        return number + 1

    }

    return addOne

}


var increment = makeIncrementer()

increment(8)


//a function receives a return value from a function

//as a parameter

// Blocks of codes that call be called later

func hasAnyMatches(list:[Int], condition:(Int)->Bool)->Bool{

    for item in list {

        if condition(item){

            print("conditon true \(item)")

            return true

        }

        print("condition false, and item = \(item)")

    }

    return false

}

func lessThanTen(number: Int)-> Bool{

    return number < 10

}


var numbers = [20, 19, 7, 12]

hasAnyMatches(list: numbers, condition: lessThanTen)


// closure sample with no name

numbers.map({ (number:Int) -> Int in

    let result = 3 * number

    return result

})


let threeTimes = numbers.map({ (number:Int) -> Int in

    let result = 3 * number

    return result

})

print(threeTimes)


//experiment : the closure that returns 0 for all odd numbers in list

numbers.map({ (number:Int) -> Int in

    let result = number % 2

    if result == 0{

        return number

    }

    return 0

})

// when the type of closure is known

let mappedNumbers = numbers.map({ number in 3 * number})

print (mappedNumbers)


// parameters as numbers

let sortedNumbers = numbers.sorted { $0 > $1 }

let sortedNumbers2 = numbers.sorted { $0 < $1 }

print(sortedNumbers)

print(sortedNumbers2)

'초짜 IT보이 서바이벌 스토리 > iOS - swift' 카테고리의 다른 글

[swift] code log, day 4  (0) 2017.09.26
[swift] code log, day 3  (0) 2017.09.25
[swift] code log, day 2  (0) 2017.09.24
[swift] code log, day 1  (0) 2017.09.22
[swift] #SWIFT #4 언어 가이드  (0) 2017.09.22
[swift] push notification  (0) 2014.06.25

posted by Sungyoup Han matrim

iBooks 의 SWIFT 4를 통해 언어 공부 중입니다. 이때 사용된 책 속의 코드 및 연습문제 등의 코드 로그입니다.



아래 코드들은 Github 에서도 다운받을 수 있습니다.

SWIFT_Playground_Excersice: https://github.com/youp-han/SWIFT_Playground_Excersice


코드 로그 입니다.


//Day 1


//: Playground - noun: a place where people can play


import UIKit


//Simple Values

//decraring variables

var str = "Hello, playground"

let implictInteger = 80

let explicit:Double = 80

let explicit1: Float = 80


let label = "the width is"

let width = 83

let widthLabel = label + String(width)


print("hello world")


let apples = 3

let oranges = 4


let applesSummary = "I have \(8.0) apples"

let fruitSummary = "I have \(8.0 + 10.0) pieces of fruit"


//array and dictionary

var shoppingList = ["catfish", "water", "tulips", "blue paint"]

shoppingList[1] = "bottle of water"


var occupations = [

    "Malcolm" : "Captain",

    "Kaylee" : "Mechanic",

]

occupations["Jayne"] = "Public Relations"


let emptyArray = [String]()

let emptyDictionary = [String:Float]()


//Control Flow

//for loop & if else

let individualScores = [12, 14, 25, 34, 134]

var teamScore = 0

for score in individualScores {

    if score > 30 {

        teamScore+=3

    } else {

        teamScore+=1

    }

}

print(teamScore)


//optional variable

var optionalString: String? = "Hello"

print(optionalString == nil)

var optionalName: String? = "John Appleseed"

var greeting = "Hello!"


if let name = optionalName {

    greeting = "hello, \(name)"

}


let nickName: String? = nil

let fullName: String = "John Appleseed"

let informalGreeting = "Hi \(nickName ?? fullName)"


//switch

let vegetable = "red pepper"

switch vegetable{

case "celery":

    print("wawa")

case "cucumber", "watercress":

    print("wwwwww")

case let x where x.hasSuffix("pepper"):

    print("wow found red pepper")

default:

    print("default")

}


//dictionary

let interestingNumbers = [

    "prime":[2,3,5,7,11,13],

    "fibonacci":[1,1,2,3,5,8],

    "square":[1,4,9,16,25],

]


var largest = 0


for (kind, numbers) in interestingNumbers {

    for number in numbers {

        if number > largest {

            largest = number

        }

        print(kind + ":" + String(largest))

    }

}

print(largest)



//while

var n=2

while n<100 {

    n *= 2

}

print(n)


var m = 2

repeat {

    m *= 2

} while m < 100


print (m)


// range

var total = 0


// .. vs =< ...

for i in 0..<4 {

    total += i

    print (total)

}

print (total)


//function and Closure

//function

func greet(person: String, day: String) -> String {

    return "Hello \(person), Today is \(day)."

}

greet(person: "Bob", day: "Friday")


func greetWithSpecial(person: String, special: String)->String{

    return "Hello \(person), Today's Lunch Special is \(special)."

}

greetWithSpecial(person: "Mike", special: "Meat Balls")


// _ <-- 추가 하여 함수 호출 시 argument label 를 쓰지 않게 한다.

func greet(_ person: String, day: String) -> String {

    return "Hello \(person), Today is \(day)."

}

greet("Sam", day: "Saturday")



//tuple , returns multiple results

func calculateStatistics(scores:[Int]) -> (min: Int, max: Int, sum: Int){

    var min = scores[0]

    var max = scores[0]

    var sum = 0

    

    for score in scores {

        

        if score > max {

            max = score

        } else if score < min {

            min = score

        }

        sum += score

    }

    return (min, max, sum)

}


let statistics = calculateStatistics(scores: [1,2,3,4,5,6,7,8,9,10])

print(statistics.min)

print(statistics.max)

print(statistics.sum)

print(statistics.0)

print(statistics.1)

print(statistics.2)


func sumOf(numbers: Int...)-> Int {

    var sum = 0

    for number in numbers {

        sum += number

    }

    return sum

}


sumOf()

sumOf(numbers: 1,2,3,4,5,6,7,8,9,10)


//experiment

func averageOf(numbers: Double...)-> Double{

    var average : Double = 0.0

    var counter : Double = 0.0

    var sum : Double = 0.0

    

    for number in numbers {

        sum += number

        counter += 1.0

    }

    if counter != 0.0 {

        average = sum / counter

    } else {

        average = 0.0

    }

    

    print("Sum = \(sum)")

    print("counter = \(counter)")

        

    return average

}


averageOf()

averageOf(numbers: 1,2,3,4,5,6,7,8,9,10)


func returnFifteen() -> Int{

    var y = 10

    

    func add(){

        y+=5

    }

    add()

    return y

}


returnFifteen()


'초짜 IT보이 서바이벌 스토리 > iOS - swift' 카테고리의 다른 글

[swift] code log, day 4  (0) 2017.09.26
[swift] code log, day 3  (0) 2017.09.25
[swift] code log, day 2  (0) 2017.09.24
[swift] code log, day 1  (0) 2017.09.22
[swift] #SWIFT #4 언어 가이드  (0) 2017.09.22
[swift] push notification  (0) 2014.06.25

posted by Sungyoup Han matrim

애플의 언어 가이드 링크 공유


개인적으로 공부 할 때 사용 중인 가이드 입니다. 링크 공유 합니다.


링크 : https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/index.html#//apple_ref/doc/uid/TP40014097-CH3-ID0


그리고 다음은 Swift 를 Xcode 에서 Test 하는 화면입니다.



여하튼 업그레이드 된 xCode 9 의 Playground.. 속도도 빠르고, 바로 옆에서 결과물이 보이니 열어놓고 코드 연습 하기 넘 좋습니다.



또한 iBooks 사용하여 SWIFT 3.1 도 언어 익히는데 사용 중입니다.



영문으로 되어 있지만, Playground 에서 결과물이 내용 파악 하는데 쉽도록 많은 도움이 되네요.


요즘 열공 모드 입니다. ㅋㅋ 뒤늦게 이제서야 SWIFT 익히고 있네요 :p


'초짜 IT보이 서바이벌 스토리 > iOS - swift' 카테고리의 다른 글

[swift] code log, day 4  (0) 2017.09.26
[swift] code log, day 3  (0) 2017.09.25
[swift] code log, day 2  (0) 2017.09.24
[swift] code log, day 1  (0) 2017.09.22
[swift] #SWIFT #4 언어 가이드  (0) 2017.09.22
[swift] push notification  (0) 2014.06.25

posted by Sungyoup Han matrim

iOS11 이 출시 되면서 Xcode 9 도 함께 출시 되었습니다.

어떤 내용들이 바뀌었는지 아래 영문으로 된 애플 개발자 사이트를 참고 하세요

애플 개발자 사이트 : (https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/WhatsNewXcode/xcode_9/xcode_9.html#//apple_ref/doc/uid/TP40004626-CH8-SW1)

다음은 Xcode 9 의 새로운 업데이트의 하이라이트 입니다. 

1. 새로운 에디터 

2. 리팩토링

3. 빠른 검색

4. 디버깅

5. Source Control

6. Xcode Server Built-in

7. 새로운 플레이그라운드 탬플릿

8. 새로운 빌드 시스템 

posted by Sungyoup Han matrim


iOS9 부터는 사용하지 못하는 UIAlertView

대신에 사용하는 UIAlertController 에 대해 알아봤습니다. 아래 링크에 샘플코드가  나와 있습니다.

http://rhammer.tistory.com/64

위에 소개된 샘플코드를 가지고 개인적으로 필요하여 아래 깃헙에 바꿔서 공유했습니다.

https://github.com/youp-han/AlertSampleInObjectiveC


posted by Sungyoup Han matrim



티스토리 툴바