이전 시큐리티기능을 사용하지 않고 따로 히든텍스트라든 변수를 정의해줘서 비밀번호 가리고 보이고하는 기능을 구현해놨었다

해당 스크린을 테스트하기위해 테스트코드를 짜놨었는데....

 

이번 최신 버전을 배포하던중 텍스트필드에 중대한 버그가 발견되어 텍스트필드의 시큐리티 기능을 이용하는 방식으로 전환했다

그리고.. 그 이후로 UI테스트코드를 통과하지 못하고있다

도저히 잘못된점을 모르겠어서 뷰를 하나하나 스택쌓아가듯이 찾아 나아가보지만 여전히 해당 아이디를 가진 텍스트필드를 찾을 수 없다고 오류를 뱉고있었다.

 

나의 이 멍청한 시도를 다른이는 하지 않기를 기도하며 문제점을 여기에 적는다

나는 해당 부분을 이렇게 정의하며 찾아보고있었다.

- 라인2 오류 -

let loginvcContentView = app.otherElements["loginvcScrollViewContentView"]
let pwTextField = loginvcContentView.textFields["loginvcPwTextField"]

UITest에 대해 누가 알려주지 않아 거의 그냥 막코딩이라 변수이름이라던가 방법은 그냥 넘어가줬으면 좋겠다

문제는 loginvcContentView에서 찾는 엘레먼트 타입이였다.

텍스트필드에

textField.isSecureTextEntry = true

라고 정의를 해주면 textFields로는 찾을 수 없고

아래와 같이 해줘야한다.

let loginvcContentView = app.otherElements["loginvcScrollViewContentView"]
let pwTextField = loginvcContentView.secureTextFields["loginvcPwTextField"]

그렇다 

저 속성하나 켜줬다고 textField가 아닌 secureTextFields로만 찾을 수 있게되었다.

망할

 

'iOS > swift' 카테고리의 다른 글

No such module ~~ 설치되지 않는 Snapkit 문제  (0) 2023.04.12
ios - Admob 에러코드 메모  (0) 2023.03.21
Alamofire.AFError Code  (0) 2022.10.06
Block Based KVO, iOS - contentSize  (0) 2022.09.27
Date 끼리의 비교  (0) 2022.08.04

이번글은 6. 조건문과 반복문에서 언급한 enum에 대한 글이다.

직접 만드는 자료형중에 하나라고 소개하고싶다.

정수가 여러가지 수를 모아 둔 형태라 하면 이 enum 은 사용자가 원하는것들을 모아둘수있다.

6번글에서 switch 예제로 사용한 코드를 다시보면

    var a = "banana"

    switch a {

      case "banana" : print("banana")

      case "apple" : print("apple")

      case "melon" : print("melon")

      case "lemon" : print("lemon")

      case "peach" : print("peach")

      default: print("다른 종류이다.")

    }

출처: https://wiwi-pe.tistory.com/105?category=976417 [선생님 개발블로그가 하고싶어요.:티스토리]

라고 되어 있는데.

여기서 a는 String이라는 자료형을 가지게된다.

switch는 조건으로 들어온 a가 가질수 있는 모든 값에 대해 case를 지정해줘서 조건을 분기하는 기능을 하는데

default에서 이외의 String값을 처리해주고있는데 오타라던가가 발생하면 항상 default로 빠져버린다.

여기서 만약 a가 enum이였다면 훨씬더 깔끔한 모습으로 안정적이게 바꿀수있다.

a 값이 

banana apple melon lemon peach 중 하나라면 

enum Fruit {
    case banana
    case apple
    case melon
    case lemon
    case peach
}

var a = Fruit.banana
switch a {
    case .banana : print("banana")
    case .apple : print("apple")
    case .melon : print("melon")
    case .lemon : print("lemon")
    case .peach : print("peach")
}

위와 같은 형태로 a값에 대한 오류를 사전에 방지를 할 수 있게된다.

이 이외에도 조건문의 기준으로 사용하기위해 불형 변수를 하나 사용한다하면

var flag = false

if flag { print("참일때 실행해라" }

이 항목을 

enum Some {
    case run
    case stop
}
var flag = Some.run
if flag == .run { print("참일때 실행해라") }

이와 같이 변경해서 사용하면 가독성과 확장성이 좋아진다.

가독성이야 이름때문에 그렇다해도 확장성이 왜 좋아지냐면

만약 flag가 나중에 run또는 stop이 아닌 pause를 가지게 된다면 단순히 Some에서 case pause를 추가해주면 된다. 또다른 flag를 사용하여 연속으로 if문을 중첩하여 분기를 해주는것보다 훨씬 확장성이 좋다.

다시 위의 바나나에 관한 이야기로 돌아가자면 enum자체에도 하나의 특정한 값을 가지게 할수도 있고 함수를 가지게 할 수 도 있는게 스위프트의 장점인데 이에 대해 예제로 하나 퉁치며 이번 enum을 마치려고 한다.

enum Fruit : Int {
    case banana = 12
    case apple
    case melon
    case lemon
    case peach
    
    var stringValue: String {
        get {
            switch self {
            case .apple: return "apple"
            case .banana: return "banana"
            case .lemon: return "lemon"
            case .melon: return "melon"
            case .peach: return "peach"
            }
        }
    }
}


var a = Fruit.lemon
switch a {
    case .banana :
        print("banana")
    case .apple :
        print("apple")
    case .melon :
        print("melon")
    case .lemon :
        print("lemon")
    case .peach :
        print("peach")
}
print(a.rawValue, a.stringValue)

이 코드를 실행해보면

lemon

15 lemon 

와 같은 두줄이 뜨게 되는데 첫줄은 switch문에의한 print이고 두번째 줄은 switch 이후의 print문이다.

enum은 rawValue를 지정해줘서 가져올수 있는데 

rawValue를 위에 banana = 12 로만 주면 아래에 들어가는 값을 자동으로 순서대로 지정된다.

추가로 enum에는 stringValue처럼 값을 지정해주거나 func을 새로 넣어 줄 수 있어 조건문같은와 같이 쓰기 매우 좋은 형태이다.

 

- 변수에 대괄호를 열어 get을 정의해줬는데 이에 대해서는 앞 글에서 다루지 않아 이후에 또 다룰수 있으면 좋겠다.

- 함수에 대해서도 다룬적이없다.

Swfit의 compare를 이용하면 Date끼리의 비교도 가능하다.

이글에서 할 순서는

1. 동일 문자열 형식으로 비교할 값을 정의한다.

2. 동일한 DateFormatter로 String 을 Date 형으로 변경한다

3. 비교

비교할 형식은이다 "yyyy-MM-dd "

아래는 gist로 작성한 예제 코드이다.

 

compare는 Same, DESC, ASC로 세가지의 결과를 반환해주는데

이를 이용해 Date 끼리의 비교를 따로 함수로 정의해서 사용하거나 바로 이렇게 사용할수 있다.

https://stackoverflow.com/questions/18946302/uinavigationcontroller-interactive-pop-gesture-not-working

UINavigationController에 붙어있는 ViewController이지만백제스쳐가 동작하지 않는 경우가 왕왕있다.

 

해당 문제는 제스쳐 이벤트 끼리의 충돌문제인것으로 보인다이때 네비게이션 제스쳐를 하나의 UINavigationController 내부의 viewControllers개수가 하나보다 많을때만 동작하도록 지정해주는 걸 달아주면 이상하게도 동작을 잘한다.

 

해당 소스는 상단 스택오버플로우의 답에 달린 코드이다.

class NavigationController: UINavigationController, UIGestureRecognizerDelegate {

    /// Custom back buttons disable the interactive pop animation
    /// To enable it back we set the recognizer to `self`
    override func viewDidLoad() {
        super.viewDidLoad()
        interactivePopGestureRecognizer?.delegate = self
    }

    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        return viewControllers.count > 1
    }

}

pickerView는 label이나 button처럼 손쉽게 텍스트에 대한 접근을 할 수 없다.

생긴것부터가 배열이니 배열 전체에 대해 어떻게 해줄까를 정해줘야되서 그렇게 해둔듯 하다.

그러한 부분을 어떻게 할지를 정하는 함수가 pickerview에는 있다.

 

func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString?

 

라는 함수 인데

텍스트를 그냥 넣어 줄때 사용하는 

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?

와 사용이 비슷하다.

 

아래는 빨간색으로 변경하는 예시를 플레이그라운드에서 만들어 보았다.

텍스트 설정을 변경하는 키값이 상당히 많은데 그중에서도

foregroundColor

를 사용했다.

 

위 소스를 플레이그라운드에서 돌리면 아래와 같이 나온다.

 

아래는 키들에 대한 애플문서이다.

https://developer.apple.com/documentation/foundation/nsattributedstring/key

 

Apple Developer Documentation

 

developer.apple.com

 

'iOS > swift' 카테고리의 다른 글

KeyboardObserver~  (0) 2021.10.19
Guide Swift Programming Language 5.5  (0) 2021.10.01
프로그래머스 - 프린터  (0) 2021.05.06
프로그래머스 - 기능개발  (0) 2021.05.05
프로그래머스 - 모의고사  (0) 2021.05.04

기본연산자 목록에 안넣어버린 논리연산자다.

이전에 데이터 타입 불을 다룰때 잠깐 했던거 같기도하다.

 

논리 연산은

참과 거짓에 대해 연산하는거다 그래서 기본적으로 boolean형식으로 값이 나온다.

 

Logical Not Operator

not 연산은 불 연산을 뒤집는연산이다.

만약 참에 대해 not 을 붙이면 거짓이 되고

거짓에 대해 not을 붙이면 참이된다.

 

not 연산자는 느낌표를 붙이면된다.

 

ex1:

        var target = false
        print(!target)
        
        target = !target
        print(target)

결과:

true

true

 

처음 target이 false이지만 print할때 ! 를, not 연산자를 붙여서 print할땐 true가 출력된다.

그다음엔 target에 !target을 해서 true값으로 변경된다.

 

Logical And Operator

and 연산은 두 불형식 값이 모두 참일때 참으로 결과가 나오는 연산이다.

 

연산자로는 &&를 사용한다.

단 여러 if문이 겹치는형태를 축약하는 형태로 같은 and역할을 하게 끔 할 수도 있다 

ex2)

        let target1 = false
        let target2 = true
        let target3 = true
        
        if target1 && target2 {
            print("이 글은 출력되지 않는다.")
        }
        
        if target2 && target3 {
            print("두 값은 모두 참이다.")
        }
        
        if target2, target3 {
            print("이렇게도 쓴다.")
        }
        
        if target1, target3 {
            print("이 글은 출력되지 않는다.")
        }

결과:

두 값은 모두 참이다.

이렇게도 쓴다.

 

 

 

Logical Or Operator

and를 했으니 이제 or이다.

둘중 하나만 참이면 참으로 결과가 나오는 연산이다.

 

위의 예제를 살짝 바꿔서 아래 예시를 만들어봤다.

 

ex2)

        let target1 = false
        let target2 = true
        let target3 = true
        
        if target1 || target2 {
            print("이 글이 출력된다")
        }
        
        if target2 || target3 {
            print("두 값중 하나는 참이다.")
        }

결과:

이 글이 출력된다

두 값중 하나는 참이다.

 

 

연산자 파트를 모두 끝냈다!

다음엔 어떤 기본 강좌를 할지는 모르겠다.

 

programmers.co.kr/learn/courses/30/lessons/42587

 

코딩테스트 연습 - 프린터

일반적인 프린터는 인쇄 요청이 들어온 순서대로 인쇄합니다. 그렇기 때문에 중요한 문서가 나중에 인쇄될 수 있습니다. 이런 문제를 보완하기 위해 중요도가 높은 문서를 먼저 인쇄하는 프린

programmers.co.kr

이번 문제는 배열이 주어지고 정렬하는 문제로 보았다.

 

실 답을 구하려면 굳이 id를 정하고 정렬할 필요는 없어 보이지만 

실제 프린터라고 생각해서 하나의 작업에 대해 id를 각각 추가하여 작성해봤다.

 

정렬 순서는 문제에서 제시해준 3단계를 그대로 따라하면 간단히 된다.

 

난 총 세부분으로 소스를 나눠 작성했다

 

첫번째 - 주어진 priorities에 각각 id를 지정

두번째 - priorities를 정렬(

문제에서 주어짐, 첫번째 목록의 우선순위가 대기중인 작업의 우선순위보다 낮다면 무조건 대기순위 뒤로 이동 

대기중인 작업중 우선 순위가 더 큰게 없다면 대기순위에서 제거)

 

세번째 - 찾으려는 타깃이 언제 완료되는가 리턴 

 

 

  struct Work {
    let id:Character
    let priority:Int
  }
  
  func solution(_ priorities:[Int], _ location:Int) -> Int {
    var works = [Work]()
    var endArray = [Work]()
    var lastId:Character = "a"
    for priority in priorities {
      let work = Work(id: lastId, priority: priority)
      lastId = Character(Unicode.Scalar((lastId.unicodeScalars.first!.value) + 1)!)
      works.append(work)
    }

    guard location < works.count else { return -1 }
    let findTarget = works[location]
    
    while works.count > 0 {
      let target = works[0]
      var notFind = true
      for i in 1 ..< works.count {
        // 뒷 대기열에 큰게 있다면 notFind = false
      }
      if notFind {
      // 대기열에서 제거 endArray에 추가
      }
    }

    for i in 0 ..< endArray.count {
    // 찾으려는 id와 같은것의 i값 리턴
    }
    
    return -1
  }

 

 

전체 소스는 아래 깃허브 페이지에 있다.

github.com/wiwi-git/Programmers-learn/blob/master/swift/Practice/Practice/Printer.swift

 

wiwi-git/Programmers-learn

Contribute to wiwi-git/Programmers-learn development by creating an account on GitHub.

github.com

 

programmers.co.kr/learn/courses/30/lessons/42586

 

코딩테스트 연습 - 기능개발

프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다. 또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는

programmers.co.kr

스택/큐 분류에 들어있는 문제다.

 

퍼센트지가 들어있는 배열(progresses)이 각각 루프 1당(문제에서의 하루) speeds 배열의 값 만큼 진행되어서

퍼센트지가 100%로 다 채워졌을때가 몇 루프인지 계산하는 문제이다.

 

계산시에 progresses의 값이 들어있는 순서대로 뒷 값이 작은게 몇개인지 저장하고 그 값을 리턴해주면 된다.

 

나는 우선 퍼센트지가 전부다 찼을때의 루프수를 저장해놓기위해 complete배열을 progresses배열의 수 만큼 작성해두고.

progresses를 foreach문을 통해 

내부에 while문으로 퍼센트치를 채워넣으면서 루프수(foreach문안의 변수 day)를 저장했다

 

그후 while문을 통해 complete배열이 앞값과 뒷값을 비교해가며 뒷값이 작을때 +1 뒷값이 클때 다시1 부터 카운트식으로 하여 코드를 짯다.

 

총 두 두분으로 나눠서 했다.

 

    var complete = Array<Int>(repeating: 0, count: progresses.count)
    
    for (i, persent) in progresses.enumerated() {
      var day = 0
      var persent = persent
      while persent < 100 {
        persent += speeds[i]
        day += 1
      }
      complete[i] = day
    }
    
    var i = 0
    var result = [Int]()
    while i < complete.count {
      var commit = 1
      if (i + 1) >= complete.count {
        result.append(commit)
        break
      }
      
      for k in (i + 1) ..< complete.count {
        if complete[i] >= complete[k] {
          commit += 1
        } else { break }
      }
      
      i += commit
      result.append(commit)
    }
    return result

라인 자체는 적어보이는데 두 번째 루프문부분, 값비교하는 부분이 뭔가 찝찝하다 

하지만 채점결과는 통과하니 그냥 넘어가련다. 생각하기 귀찮아졌다.

 

아래링크는 해당 소스가 올려놓은 깃허브 페이지이다.

 

github.com/wiwi-git/Programmers-learn/blob/master/swift/Practice/Practice/FunctionDevelopment.swift

 

wiwi-git/Programmers-learn

Contribute to wiwi-git/Programmers-learn development by creating an account on GitHub.

github.com

 

+ Recent posts