cocoapod으로 Snapkit 5.6.0 버전을 다운받아 사용중이였는데

작업 pc변경이후 계속 모듈을 찾을 수 없다는 빌드 에러가 떠서 곤란하게되었다.

실제로 다운받은 파일을 확인해보면 pod으로 받은 다른 파일들은 확인되나 Snapkit만이 폴더만 생성되고 라이브러리의 정보만 담은 파일이 있을뿐 실 코드들이 없다.

이 문제때문에 우선적으로 많이 하는 해결책으로

clean build folder를 돌려보았고.

pod로 받는 파일들을 새롭게 받아보아보았고

DerivedData 폴더를 비워보았으나 역시나 되지 않는다.

 

이런 문제로 사용한 해결방법 아래와같다

1. pod repo update ( podsepc 업데이트 ) 

2. clean build folder ( 기본 단축키 cmd + shift + k )

3. Podfile.lock 삭제

4. Pods폴더 삭제

5. DerivedData 폴더 내부 비움 ( 설정된 DerivedData 폴더의 경로는 xcode의 Preferences... -> Locations 에서 Derived Data 항목으로 알 수 있다.

6. pod install

이제 다시 Pods의 Snapkit 폴더를 찾아보면 무사히 코드들이 다운받아졌음을 알 수 있다

 

 

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

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

 

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

그리고.. 그 이후로 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

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

스크롤뷰에

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 집어 넣는 부분이 아직도 잘 이해가 안간다.

누가 알려줄 사람은 없나

 

 

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. 해피엔딩

 

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

Attempted to scroll the collection view to an out-of-bounds item (0) when there are only 0 items in section 0.

 

늦은 업데이트를 진행하였고 시뮬레이터가 15.2가 되었다.

회사 프로젝트를 돌려보던중 시뮬레이터에서 위와 같은 에러가 나면서 종료가 되고있다.

 

내용만 봐선 "아이템이 0인데 스크롤을 0으로 하려고한다 그러지마 "  라며 친절히 문제되는 부분을 알려주지만

 

이전에는 됐는데?

 

참담한 심정으로 콜렉션뷰의 스크롤하는 부분

      self.collectionView.scrollToItem

부분을

if (.count != 0 ) 를 걸어주어 0 이후에 변경될때만 호출해주도록 변경하였다.

 

동작은 한다

 

뭔가 미묘한 기분

UI Test의 자동화를 추가 해보려고했다.

 

Appium을 먼저 시도를 했으나 이상하게도 시뮬레이터에서 어마어마게 지연현상이 일어나고 이러면 그냥 손으로하는게 더빠르겠다 싶어서 포기한적이 있었다. 

무엇이 문제였는지는 아직도 모르겠다.

 

그리고 이제 다시 Detox로 해보려고 한다.

 

사실 디톡스의 홈페이지에 방법이 적혀있다

디톡스를 적용해볼 사람은 굳이 이글을 읽지말고

https://wix.github.io/Detox/docs/introduction/getting-started/ 

 

Getting Started | Detox

Getting Started

wix.github.io

를 보는게 좋다고 본다.

 

일단 필요한 도구들을 설치해준다.

npm install -g detox-cli

npm install detox --save-dev

디톡스들을 설치해주고

설정은 나중에 할거다.

 

그전에 문서에 이러한 항목이 있다.

Tip: Remember to add the node_modules folder to your git ignore file (e.g. .gitignore).

gitignore에 무시항목을 꼭 넣어주라는 말인데 

이걸 안해주면 모든 파일이 깃에 추가되어 특히 라이브러리들이 많은 리엑트 네이티브에서는 깃관리의 헬이 벌어진다.

프로젝트의 루트폴더에 .gitignore 라는 숨긴파일이 있을것이고 

해당 내용을 수정해주면된다.

폴더 자체를 관리 안할수도있고

파일 확장자별로도 관리 안할 수도 있고

여러가지가 있다.

 

 

디톡스를 설정하기전  나는 프로젝트가 제대로 시뮬레이터상에서 동작하는지 확인을 해야한다고 생각한다.

그래서 첫단계는

1. npm i 

로 라이브러리 먼저 설치한다.

여러가지 버전 문제로 실제로나는

 

npm i --force

 

의 명령어를 프로젝트 루트 폴더에서 실행시켰다.

 

그 다음은 ios 의 라이브러리를 설치한다.

cd ios && pod install --repo-update

 

왜 레포지토리의 업데이트도 같이 하는지는 내 프로젝트에서 사용중인 firebase 관련 라이브러리들이 이상하게 버전이 계속 어긋난다.

이럴때 --repo-update 옵션을 붙이니 잘맞게 설치가 되었다.

 

이제 iOS시뮬레이터로 돌아가는지 테스트를 해본다.

 

npx react-native run-ios --simulator="iPhone 12 mini"

 

시뮬레이터 옵션을 붙이는 이유는 맥북의 용량이 적기에 필요한 시뮬레이터만 남기고 죄다 삭제해버렸다.

그래서 기본으로 잡히는 시뮬레이터가 존재하지않는다는 에러를 뱉기에 따로 지정해줬다.

 

안드로이드는.... 결론만 말하자면 실패했다 이에 대해서는 후반부에 다시 적을 것이다.

iOS가 정상적으로 돌아가기에 이제 설정해줬다

 

detox init

를 실행한다.

 

디톡스에대한 설정을 package.json에 설정해줘도 된다고 적혀있지만

난 .detoxrc.json에 설정해줬다.

아래는 공식문서에 적힌 형식이다.

{
  "devices": {
    "simulator": {
      "type": "ios.simulator",
      "device": {
        "type": "iPhone 12 Pro Max"
      }
    }
  },
  "apps": {
    "ios.release": {
      "name": "YourProject",
      "type": "ios.app",
      "binaryPath": "ios/build/Build/Products/Release-iphonesimulator/YourProject.app",
      "build": "xcodebuild -project ios/YourProject.xcodeproj -scheme YourProject -sdk iphonesimulator -derivedDataPath ios/build"
    }
  },
  "configurations": {
    "ios.sim.release": {
      "device": "simulator",
      "app": "ios.release"
    }
  }
}

뭔가 많다.

release라고 뒤에 붙은 애들과 따로 debug용으로 나눌수 있어서 이렇게 한것으로 보이나

난 디버그용이면 충분하다고 생각한다.

 

그래서 나는 아래와 같이 설정했다.

{
    "testRunner": "jest",
    "runnerConfig": "e2e/config.json",
    "skipLegacyWorkersInjection": true,
    "apps": {
      "ios": {
        "name":"<AppName>",
        "type": "ios.app",
        "build": "xcodebuild -workspace ios/<ProjectName>.xcworkspace -scheme <ProjectName> -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build",
        "binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/<ProjectName>.app"
      }
    },
    "devices": {
      "simulator": {
        "type": "ios.simulator",
        "device": {
          "type": "iPhone 12 mini"
        }
      },
      "emulator": {
        "type": "android.emulator",
        "device": {
          "avdName": "Pixel_API_28_AOSP"
        }
      }
    },
    "configurations": {
      "ios": {
        "device": "simulator",
        "app": "ios"
      },
      "android": {
        "device": "emulator",
        "app": "android"
      }
    }
  }

 

ios는 여타 다른 설정이 굳이 필요하지 않다

바로 e2e폴더에 테스트 코드를 넣고 돌리면 된다.

 

예제용 코드

describe("First UI test1", () => {

  it("should show Step One", async () => {
    await device.launchApp();
    await expect(element(by.text("Step One"))).toBeVisible();
  });

  it("should show Debug", async () => {
    await expect(element(by.text("Debug"))).toBeVisible();
  });

  it("should show \"Learn More", async () => {
    await expect(element(by.text("Learn More"))).toBeVisible();
  });
});

주의점은

if가 아니라 it이라는것과

여러 it이 있지만 하나라도 뭔가 이상하면 테스트가 없다고 에러가 날수 있다는점과

해당 코드들 기본으로 쓰이는 expect나 it , element 등등에 대한 import가 위에 적용될시 에러가 날 수 있다는점이다.

이런한 점때문에 시간을 참 많이 날렸다.

 

 

테스트를 돌릴려면 빌드가 필요하다.

detox build --configuration <your configuration name>

를 프로젝트 루트에서 실행해서 에러를 잡으면된다

 

나는

detox build --c ios

로 돌렸다.


configuration 을 c로도 동작한다는게 공식페이지에선 보이지 않는다.

 

테스트 코드를 실행하려면

detox test --configuration <your configuration name>

로 실행을 하면 기존 설치된앱이 삭제되고 새로 깔리며 실행된다.

 

나는

detox test -c ios 

로 돌렸다.

 

 

추가적인 팁을 적자면

 

각 파트별을 컴포넌트화 하여 임포트 시켜 사용할 수 있다.

난 긴 명령어를 간단하게 작성하려고 컴포넌트화를 시켜서 사용했다

다른 라이브러리를 임포트하여 ( axios )네트워크 통신도 넣어볼수있다.

- 어디선가 본 글에는 이러한 네트워크 통신을 테스트코드에 넣지말고 임의로 값을 반환해서 마치 값을 잘 받아온것처럼 하라고 하여서 서버 부담을 없애야한다고 했다. 만 나는 그냥 돌렸다.

 

 

 

iOS - 끝!

 

다음글은 결국 실패하고 기약을 알 수 없이 미뤄버린 안드로이드에대한 글이다.

 

'React Native' 카테고리의 다른 글

rn 에서 android 뷰 사용하기.  (0) 2022.03.02
굳이 jsx를 사용하고싶다.  (0) 2022.01.05
npm install을 주의하라  (0) 2021.10.22
npm version downgrade  (0) 2021.07.12
SafeAreaView의 상단을 참조안하는 방법에 대해  (0) 2021.07.07

 

자료 소스 - https://developer.apple.com

19년도엔 iOS13버전이 50% 였으나 

1년 사이 18%로 뚝 떨어졌습니다.

 

하지만 여전히 13버전을 최소 타깃으로 잡기에는 최신기종의 지원 os버전만 보면 아직도 종종 보이는 아이폰 6+기종은 iOS12까지만 지원하기에 

최소 타깃은 작년과 마찬가지로 12버전으로 잡고 개발하는게 좋을것으로 보입니다.

물론 비율자체가 그리 큰 비율이 아니고  아이폰6s부터는 13버전까지 지원하기에 iOS13버전을 최소타깃으로 잡아도 무방합니다.

 

 

+ Recent posts