Search

'Swift'에 해당되는 글 4건

  1. 2020.11.23 codable
  2. 2020.11.23 closure
  3. 2020.11.23 segue
  4. 2020.11.21 Delegate

codable

컴퓨터공부/iOS 2020. 11. 23. 15:49 Posted by 아는 개발자

codable은 swift4에서 추가된 프로토콜로 JSON 처리를 손쉽게 해준다. 예로 서버로부터 이런 json 결과물을 받으면 

 

{
  "coord": {
    "lon": -0.13,
    "lat": 51.51
  },
  "weather": [
    {
      "id": 721,
      "main": "Haze",
      "description": "haze",
      "icon": "50n"
    }
  ],
  "base": "stations",
  "main": {
    "temp": 4.91,
    "feels_like": 1.93,
    "temp_min": 4.44,
    "temp_max": 6,
    "pressure": 1028,
    "humidity": 87
  },
  "visibility": 2800,
  "wind": {
    "speed": 2.1,
    "deg": 230
  },
  "clouds": {
    "all": 71
  },
  "dt": 1606106846,
  "sys": {
    "type": 1,
    "id": 1414,
    "country": "GB",
    "sunrise": 1606116755,
    "sunset": 1606147310
  },
  "timezone": 0,
  "id": 2643743,
  "name": "London",
  "cod": 200
}

 

Codable과 Struct을 조합해서 필요한 값들을 추출해줄 수 있다. JSON 값의 key와 데이터 타입만 일치하면 받아오는데는 문제 없다.

 

struct WeatherData: Codable {
    let name: String
    let main: Main
    let weather: [Weather]
}

struct Main: Codable {
    let temp: Double
}

struct Weather: Codable {
    let id: Int
    let description: String
}

////
func parseJSON(_ weatherData: Data) -> WeatherModel? {
    let decoder = JSONDecoder()
    
    do {
        let decodedData = try decoder.decode(WeatherData.self, from: weatherData)
        
        let id = decodedData.weather[0].id
        let temp = decodedData.main.temp
        let name = decodedData.name
        let weather = WeatherModel(conditionId: id, cityName: name, temperature: temp)
        return weather
    } catch {
        delegate?.didFailWithError(error)
        return nil
    }
}

'컴퓨터공부 > iOS' 카테고리의 다른 글

Pod  (0) 2020.11.30
tableview  (0) 2020.11.24
codable  (0) 2020.11.23
extension  (0) 2020.11.23
closure  (0) 2020.11.23
segue  (0) 2020.11.23
TAG Codable, ios, Swift

closure

컴퓨터공부/iOS 2020. 11. 23. 13:37 Posted by 아는 개발자

프로그래밍 함수에서는 int, float 같은 데이터 타입 인자 뿐만 아니라 함수를 전달할 수도 있는데 swift에서도 동일하게 가능하다. 함수의 인자로는 이미 있는 함수를 넣을 수 있고 뿐만 아니라 클로저(closure)의 형태로 익명의 함수(anonymous)를 만들어서 쓰는 것도 가능하다. 예로 아래에 있는 코드들은 모두 동일한 기능을 하는데 함수를 전달하는 것과 다른 클로저 형태를 사용한 것만 다르다. 자바나 코틀린을 써본 사람들은 람다 함수라는 이름으로 이미 익숙할 것이다.

 

func calculator (n1: Int, n2: Int, operation: (Int, Int) -> Int) -> Int {
    return operation(n1, n2)
}

func multiply(no1: Int, no2: Int) -> Int {
    return no1 * no2
}

let res1 = calculator(n1: 2, n2: 3, operation: multiply)
let res2 = calculator(n1: 2, n2: 3, operation: { (no1: Int, no2: Int) -> Int in
    return no1 * no2
})
let res3 = calculator(n1: 2, n2: 3, operation: { (no1, no2) in no1 * no2 })
let res4 = calculator(n1: 2, n2: 3, operation: { $0 * $1 })

print("res1: \(res1) res2: \(res2) res3: \(res3) res4: \(res4)")

각 함수의 결과값은 6으로 모두 동일하다

클로저를 쓰면 함수를 짧고 유연하게 만들 수 있다는 장점이 있다. 하지만 $0, $1 까지 사용하면 가독성(readability)이 떨어질 수도 있기 때문에 적재적소에 사용하는 것이 좋겠다.

'컴퓨터공부 > iOS' 카테고리의 다른 글

codable  (0) 2020.11.23
extension  (0) 2020.11.23
closure  (0) 2020.11.23
segue  (0) 2020.11.23
protocol  (0) 2020.11.21
Delegate  (0) 2020.11.21

segue

컴퓨터공부/iOS 2020. 11. 23. 12:24 Posted by 아는 개발자

segue(세그웨이)는 swift에선 ViewController 간의 전환하는 용도로 사용하는 라이브러리인데 ViewController가 하나의 화면을 담당하므로 화면 전환을 위한 라이브러리라고 봐도 될 것 같다. segue 가 포르투갈어로 팔로우라는 뜻을 가지고 있으니 단어의 의미와 함께 용도를 기억하면 좋을 것 같다.

 

세그웨이는 뷰 컨트롤러간의 연결을 통해서 만들수 있다. 스토리보드에서 작업중인 두개의 뷰컨트롤러중 화면전환이 시작되는 곳에서 도착지점까지 컨트롤을 눌러서 쭉 끌어준다. 실제 코드에 바인딩 해줄때 처럼 말이다. 

 

xcode는 왜이렇게 드래그를 좋아하는 걸까

 

옮기고 나면 위 그림의 파란색 박스로 표시한 새로운 아이템이 생긴다. 클릭하면 오른쪽 상단에서 세부 속성을 정의해 줄 수 있는데 identifier와 종류를 선택할 수 있다. identifier는 화면 전환 이벤트의 id와 같은 개념이고 kind는 새로운 view controller를 어떻게 띄워줄지를 선택 할 수 있다. 선호하는 방식대로 띄워주면 된다.

 

 

스토리보드에서 화면 전환에 대해서 정의한 후 ViewController에선 앞서 정의한 액션을 호출하는 역할을 한다. 아래 코드를 보면 calculatePressed 라고 스토리보드에 바인딩된 함수에서 performSegue 함수를 호출한다. 이때 withIdentifier에 들어가는 인자를 보면 아까 스토리보드에서 정의한 identifier와 동일한 값이 들어가있는걸 볼 수 있다. identifier 값을 확인해서 어떤 세그웨이를 사용할 지 선택하는 것이다. 

 

    @IBAction func calculatePressed(_ sender: UIButton) {
        print(heightSlider.value)
        print(weightSlider.value)
        
        let height = heightSlider.value
        let weight = weightSlider.value
        
        calculatorBrain.updateBmi(height, weight)

        self.performSegue(withIdentifier: "goToResult", sender: self)
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "goToResult" {
            let destinationVC = segue.destination as! ResultViewController
            
            destinationVC.bmiValue = calculatorBrain.bmi
        }
    }

 

performSegue 함수를 호출하면 아래 오버라이딩된 prepare 함수가 호출되는데 이때 어떤 세그웨이가 호출됐는지 인자를 확인 할 수 있고 새로 생성된 ViewController 함수를 볼 수 있다. 위 코드를 보면 세그웨이의 도착점을 ResultViewController 클래스로 타입 캐스팅 한 것을 볼 수 있다. 그리고 새로운 ViewController에 전달하고 싶은 bmiValue를 입력하고 있는 것도 볼 수 있다.

'컴퓨터공부 > iOS' 카테고리의 다른 글

codable  (0) 2020.11.23
extension  (0) 2020.11.23
closure  (0) 2020.11.23
segue  (0) 2020.11.23
protocol  (0) 2020.11.21
Delegate  (0) 2020.11.21

Delegate

컴퓨터공부/iOS 2020. 11. 21. 16:02 Posted by 아는 개발자

swift 언어에서 사용하는 delegate 패턴은 용어에도 담긴 의미 처럼 특정한 작업을 다른 클래스에 위임 할 때 사용하는 디자인 패턴이다. 프로그래밍을 처음 경험하는 사람들은 어렵게 느낄 수 있으나 다른 언어를 먼저 경험해본 사람들한테는 콜백과 비슷한 사용 용도라고 될 것 같다. UI 클래스에서 주로 사용하는데 UITextField 클래스에서 사용 예시를 한번 확인해보자.

 

 

위 그림의 상단에 사용자로부터 텍스트를 받을 수 있도록 UITextField를 만들어뒀다. 시뮬레이터에서 유저가 이 영역을 클릭하면 자동으로 키보드가 올라오게 되는데 UITextField만 추가하고 아무런 추가 작업이 없었다면 엔터에 해당하는 이동 버튼을 눌러도 아무런 응답이 없다. 엔터 명령에 대해서 어떤 클래스도 이 작업을 위임 받지 않았기 때문이다.

 

iOS 상에선 특정 TextField 내에서 엔터 명령은 UITextField 내부적으로 처리하고 있다. 유저가 엔터를 여러번 클릭할 수록 UITextField 내부에서는 엔터 명령을 받게 된다. 개발자가 할 일은 UITextField의 엔터 작업을 위임 받을 클래스를 선언하고 그에 해당하는 명령을 처리하는 것이다. 다양한 방법으로 이 작업을 할 수 있는데 일반적으로 UITextField가 있는 ViewController에서 이 작업을 위임해준다

 

class WeatherViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var conditionImageView: UIImageView!
    @IBOutlet weak var temperatureLabel: UILabel!
    @IBOutlet weak var cityLabel: UILabel!
    @IBOutlet weak var searchTextField: UITextField!
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        searchTextField.endEditing(true)
        print(searchTextField.text!)
        
        return true
    }    

 

위의 코드를 보면 ViewController 클래스에서 UITextFieldDelegate 프로토콜을 받고 있고 이 프로토콜에 있는 textFieldShouldReturn 함수를 구현해둔 것을 볼 수 있다. 이 함수는 해당 UITextField의 키보드에서 엔터 명령이 있는 경우에 불린다. 위임 받은 클래스에선 편집 작업을 종료하고 현재 입력된 값을 출력하는 작업을 넣었다.

 

public protocol UITextFieldDelegate : NSObjectProtocol {

    
    @available(iOS 2.0, *)
    optional func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool

    @available(iOS 2.0, *)
    optional func textFieldDidBeginEditing(_ textField: UITextField)

    @available(iOS 2.0, *)
    optional func textFieldShouldEndEditing(_ textField: UITextField) -> Bool

    @available(iOS 2.0, *)
    optional func textFieldDidEndEditing(_ textField: UITextField)

 

UITextField에선 다른 작업에 대해서도 위임 받을 수 있는데 입력을 시작할 때 호출되는 textFieldDidBeginEditing 과 입력이 끝날 때 호출되는 textFieldDidEndEditing 같은 것들이 있다. 실제 코드로 따라가보면 더 많은 함수들이 있으니 구현할 때 참고해보면 좋을 것 같다.

 

이렇게 작업을 위임하는 delegate 패턴은 protocol 이라는 것을 사용해서 구현한다. 자바의 interface와 엇비슷하고 코틀린의 interface와는 아주 비슷한데 이에 대한 내용은 다음 포스트에 다루려고 한다.

'컴퓨터공부 > iOS' 카테고리의 다른 글

codable  (0) 2020.11.23
extension  (0) 2020.11.23
closure  (0) 2020.11.23
segue  (0) 2020.11.23
protocol  (0) 2020.11.21
Delegate  (0) 2020.11.21