'Alamofire', '~> 5.2'

code name
0
createUploadableFailed
1
createURLRequestFailed
2
downloadedFileMoveFailed
3 invalidURL
4
multipartEncodingFailed
5
parameterEncodingFailed
6
parameterEncoderFailed
7
requestAdaptationFailed
8
requestRetryFailed
9
responseValidationFailed
10
responseSerializationFailed
11
serverTrustEvaluationFailed
12
sessionInvalidated
13
sessionTaskFailed
14
urlRequestValidationFailed
15
explicitlyCancelled
16
sessionDeinitialized

 

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

ios - Admob 에러코드 메모  (0) 2023.03.21
XCTest, textFields["passwordTextField"] 는 찾을 수 없다.  (0) 2022.10.31
Block Based KVO, iOS - contentSize  (0) 2022.09.27
Date 끼리의 비교  (0) 2022.08.04
bringSubviewToFront(_:)  (0) 2022.06.29

기존 스크롤뷰의 컨텐츠 사이즈가 변경될때마다 작업을 해야하는게 있어서 어떻게 해줄까 고민하다 

스크롤뷰에

horizentalScrollView.addObserver(self, forKeyPath: "contentSize", options: .new, context: nil)

해주고  observeValue 를 override해줘서 받을 수 있다는 내용 그대로 따라해 준적이 있다.

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
    if let obj = object as? UIScrollView, obj == self.horizentalScrollView && keyPath == "contentSize" {
    // 작업 내용
    }
}

 

 오브젝트에 컨텐츠 사이즈 라는 키로 .new 될때마다 옵저브 벨류에서 받아서 해줄수 있구나 라며 기뻐했건만

Lint 작업을 추가하면서 이걸 변경해야되는 일이 생겼다.

Block Based KVO Violation: Prefer the new block based KVO API with keypaths when using Swift 3.2 or later. (block_based_kvo)

라며 이건 옛날 스타일이라며 나를 갈구는 xcode의 메시지에 이걸 그냥 비활성화 해줄까 고민하다 방법을 찾았다.

나는 옵저버 추가를 viewdidload에서 해줬었는데 아래와 같이 변경해줬다.

var scrollViewContentSizeObserver: NSKeyValueObservation?

override func viewDidLoad() {
...

    scrollViewContentSizeObserver = horizentalScrollView.observe(\.contentSize, options: [.new], changeHandler: { view, change in
        // 작업 내용
    })

...
}

혹시 동작을 안할까봐 걱정을 많이 했으나 시뮬레이터 상에서는 멀쩡히 돌아가서 다행이다.

솔직히 저 contentSize 집어 넣는 부분이 아직도 잘 이해가 안간다.

누가 알려줄 사람은 없나

 

 

이번글은 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을 정의해줬는데 이에 대해서는 앞 글에서 다루지 않아 이후에 또 다룰수 있으면 좋겠다.

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

1. let 과 var 그리고 print 함수( https://wiwi-pe.tistory.com/88?category=976417 )

2. 할당연산자와 덧셈과 뺄셈 ( https://wiwi-pe.tistory.com/91?category=976417 )

3. 스위프트에서의 자료형, 그리고 옵셔널 ( https://wiwi-pe.tistory.com/97?category=976417 )

4. 곱셈과 나눗셈 그리고 복합할당연산자 ( https://wiwi-pe.tistory.com/99?category=976417 )

5. 비교 연산자 ( https://wiwi-pe.tistory.com/100?category=976417 )

6. 조건문과 반복문 ( https://wiwi-pe.tistory.com/105?category=976417

7. 3항 연산자 ( https://wiwi-pe.tistory.com/106?category=976417 )

8. nil-coalescing 연산자 ( https://wiwi-pe.tistory.com/107?category=976417 )

9. 범위 연산자 ( https://wiwi-pe.tistory.com/119?category=976417 )

10. 논리 연산자 ( https://wiwi-pe.tistory.com/120?category=976417 )

11. 열거형 enum ( https://wiwi-pe.tistory.com/216 )

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

이글에서 할 순서는

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

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

3. 비교

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

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

 

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

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

https://github.com/Lee-WonJun/JDD-Description

 

GitHub - Lee-WonJun/JDD-Description: Ju-Dung-A-Li Driven Development

Ju-Dung-A-Li Driven Development. Contribute to Lee-WonJun/JDD-Description development by creating an account on GitHub.

github.com

 

JDD (Ju-Dung-A-Li Driven Development/주둥아리 주도 개발)

 

JDD 는 아래와 같은 중요 가치를 따른다.

우리는

- 남이 쓰는 기술보다는 내 것을

- Clean 한 코드보다는 Tricky 한 것을

- 버그 Fix 보다는 변명을

- 귀찮음보다는 편함을

가치있게 여긴다. 이 말은, 왼쪽에 있는 것들은 귀찮고 오른쪽에 있는 것들은 편하기 때문에 더 높은 가치를 둔다는 것이다.

https://developer.apple.com/documentation/uikit/uiview/1622541-bringsubviewtofront

 

Apple Developer Documentation

 

developer.apple.com

 

쓰다보면 항상 헷갈려서 검색하게되어 글을 남겨본다

swift로 앱을 만들다보면 하나의 부모뷰에 여러 자식들이 들어가게 되는데

겹쳐있는 자식들중 하나를 맨앞으로 끌어오고싶을때 쓰는 메소드이다.

쓰는 방법은

부모뷰.bringSubviewToFront(맨앞으로 당길 자식뷰)

ex: https://www.hackingwithswift.com/example-code/uikit/how-to-bring-a-subview-to-the-front-of-a-uiview )

parentView.bringSubviewToFront(childView)

다음엔 잊지않기를 바란다

Showing All Messages In  ~~~~~~~/WebP.framework/WebP(anim_decode.o), building for iOS Simulator, but linking in object file built for iOS, file ~~~~~~~~/WebP.framework/WebP for architecture arm64

라고 뜨며 앱빌드가 되지 않는다.

재택근무하며 집에 있는 맥북은 intel 기반이고 사무실은 m1이라 왔다갔다 하면서 사용되는 라이브러리가 달라 발생하는 문제로 보인다.

문구 그대로 검색하면 나오는 방법은

프로젝트 빌드 설정의 Excluded Architectures에 arm64를 넣으면 만사ok 라는데

이를 행하면 아래와 같은 오류가 발생한다.

~~/ Could not find module 'SnapKit' for target 'arm64-apple-ios-simulator'; found: x86_64-apple-ios-simulator, at: ~~~/Library/Developer/Xcode/DerivedData/Store-cnoxkdqeqkddojftbwfdqjacdaxo/Build/Products/Debug-iphonesimulator/SnapKit/SnapKit.framework/Modules/SnapKit.swiftmodule

오랜 세월을 함께한 나의 전우같은 스냅킷님에서 문제가 발생했다.

대충 보면 arm64시뮬레이터로 지정됐는데 해당 모듈을 찾을수 없다고한다.

/**

* 이쯤 되면 진짜 WebP.framework를 사용하고 싶지 않다.

* 더불어 YY이름이 여럿 붙은 오픈소스가 이용되는데 이게 다 무슨소린가 싶다

* 왓츠앱의 스티커 깃헙에서 제공해주고있는 오픈소슨데 왓츠앱이면 꽤 큰곳인데 이런 따로 오픈소스를 사용한다니 이해가 되지 않는다.

* 왓츠앱 스티커 관련 작업이라 공식에서 제공해주는걸 해야겠지싶기도 하다.

**/

여러가지를 시도해본 결과 아래와같은 절차를 행하면 동작한다.

우선

1. /Users/유저폴더/Library/Developer/Xcode/DerivedData  폴더를 비운다.

2. 프로젝트 루트폴더의 Podfile.lock 를 삭제

3. 동일 폴더의 Pod폴더를 삭제하여 설치된 파일을 삭제한다.

4. pod install --repo-update 를 실행

5. 워크스페이스파일로 프로젝트를 연다

6. 클린을 해준다 ( 쉬프트 + 커맨드 + k )

7. 프로젝트 -> 빌드 -> Excluded Architectures 에 Any iOS Simulator SDK 의 arm64 를 넣어서 빌드에서 제외해준다.

https://jusung.github.io/Xcode12-Build-Error/ 의 "1. EXCLUDED_ARCHS에 arm64를 추가" 에 해당한다.

8. Pod 프로젝트 설정에서 7번과 동일하게 Excluded Architectrues 에 arm64를 넣어준다.

9. 시뮬레이터에서 빌드 테스트.

10. 해피엔딩

 

나와 동일한 방법을 행했는데도 문제가 발생했다면 나도 모르겠다.

+ Recent posts