728x90
반응형

지금 프로젝트에서 구분자를 받아와서 해당 구분자로 기존 리소스를 스플래시로 띄우는 것을 구현해놓았다.

 

https://liveforownhappiness.tistory.com/138

 

[ React Native ] Dynamic splash screen 적용하기

현재 맡은 프로젝트가 테이블에 들어가는 앱인데,  해당 앱은 제조사가 모두 본인들의 splash screen 을 사용하고 싶어했다. 여러 라이브러리를 찾아보던중, 그냥 기존에 쓰던 splash screen 을 patch-pa

liveforownhappiness.tistory.com

 

기획쪽에서, 스플래시 스크린의 교체를 요청해왔는데,

 

초기에 스플래시 스크린의 구분자와 리소스가 바뀔확률이 0에 가깝다고 개발을 구분자와 리소스로 해놓았는데

 

앞으로도 해당 교체가 있을것 같아서

 

서버에서 url 을 받아와 구현하는 것으로 변경했다.

 

일단 서버에서 url을 받아온뒤, 해당 url을 splash 스크린에서 세팅해주도록 변경하였다.

 

일단 전에 작업되어있던 

 

RNSharedPreferences

(위에 링크 게시물 참고)

에 웹 리소스 uri 값을 native 쪽으로 내려줬다.

 

SplashScreen.java 코드를

 

public static void show(final Activity activity, final int themeResId, final boolean fullScreen, final String code, final String uri) {
if (activity == null) return;
mActivity = new WeakReference<Activity>(activity);
 
Context context = activity.getApplicationContext();
SharedPreferences sharedPref = context.getSharedPreferences(
"splash", Context.MODE_PRIVATE);

activity.runOnUiThread(new Runnable() {
 
@Override
public void run() {
if (!activity.isFinishing()) {
mSplashDialog = new Dialog(activity, themeResId);

mSplashDialog.setContentView(R.layout.launch_screen);


if(!String.valueOf(code).equals("X")){ //Beaver
// mSplashDialog.setContentView(R.layout.launch_screen);

imageView = (ImageView) mSplashDialog.findViewById(R.id.image);
// imageView = mSplashDialog.findViewById(R.id.imageView);
// imageView = this.findViewById(R.id.imageView);
Log.d("uri : ", uri);
// imageView.setImageURI(Uri.parse(uri));

 
new Thread(() -> {
try{
URL myUrl = new URL(uri);
InputStream inputStream = (InputStream)myUrl.getContent();
Drawable drawable = Drawable.createFromStream(inputStream, null);
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
imageView.setImageDrawable(drawable);
}
});
 
}catch(MalformedURLException ex){
//do exception handling here
// Log.e("error : ", ex);
}catch(IOException ex){
// Log.e("error : ", ex);
}
}).start();
 
}

// if(String.valueOf(code).equals("L")){ //LG
// mSplashDialog.setContentView(R.layout.launch_screen_lg);
// }
// if(String.valueOf(code).equals("S")){ //SK
// mSplashDialog.setContentView(R.layout.launch_screen_sk);
// }
// if(String.valueOf(code).equals("D")){ //D
// mSplashDialog.setContentView(R.layout.launch_screen_d);
// }
// if(String.valueOf(code).equals("B")){ //Beaver
// mSplashDialog.setContentView(R.layout.launch_screen);
// }



mSplashDialog.setCancelable(false);
if (fullScreen) {
setActivityAndroidP(mSplashDialog);
}
if (!mSplashDialog.isShowing()) {
mSplashDialog.show();
}
}
}
});
}

 

이렇게 수정해주었다.

 

기존 image view 에 .setImageURI(Uri.parse(uri)) 값으로 리소스를 세팅해주니

 

resolveUri failed on bad bitmap uri

 

라는 에러가 나와

 

new Thread(() -> {
try{
URL myUrl = new URL(uri);
InputStream inputStream = (InputStream)myUrl.getContent();
Drawable drawable = Drawable.createFromStream(inputStream, null);
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
imageView.setImageDrawable(drawable);
}
});
 
}catch(MalformedURLException ex){
//do exception handling here
// Log.e("error : ", ex);
}catch(IOException ex){
// Log.e("error : ", ex);
}
}).start();

 

해당 작업중 inputstream.에 url  content() 를 담아 Drawble 로 생성했다.

 

해당과정에서 통신은 새로운 Thread 에서 돌려야하기때문에 new Thread 로 새로운 쓰레드를 만들어줬고

 

또한 UI 업데이트는 메인쓰레드에서만 하기때문에, runOnUiThread 로 imageView 업데이트를 진행했다.

 

이제 서버에서 이미지링크를 내려주면 해당 이미지로 스플래시를 세팅하여 보여주고 앱이 실행된다.

728x90
반응형
728x90
반응형

현재 맡은 프로젝트가 테이블에 들어가는 앱인데, 

 

해당 앱은 제조사가 모두 본인들의 splash screen 을 사용하고 싶어했다.

 

여러 라이브러리를 찾아보던중, 그냥 기존에 쓰던 splash screen 을 patch-package 해서 사용하기로했다.

 

SplashScreen.java

 

package org.devio.rn.splashscreen;

import android.app.Activity;
import android.app.Dialog;
import android.os.Build;
import android.view.WindowManager;

import android.util.Log;
import android.content.Context;
import android.content.SharedPreferences;
import com.facebook.react.bridge.ReactApplicationContext;
import java.lang.ref.WeakReference;

/**
* SplashScreen
* 启动屏
* Author:CrazyCodeBoy
* Email:crazycodeboy@gmail.com
*/
public class SplashScreen {
private static Dialog mSplashDialog;
private static WeakReference<Activity> mActivity;

/**
* 打开启动屏
*/
public static void show(final Activity activity, final int themeResId, final boolean fullScreen, final String code ) {
if (activity == null) return;
mActivity = new WeakReference<Activity>(activity);
 
Context context = activity.getApplicationContext();
SharedPreferences sharedPref = context.getSharedPreferences(
"splash", Context.MODE_PRIVATE);

activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (!activity.isFinishing()) {
mSplashDialog = new Dialog(activity, themeResId);
mSplashDialog.setContentView(R.layout.launch_screen);
if(String.valueOf(code).equals("L")){ //LG
mSplashDialog.setContentView(R.layout.launch_screen_lg);
}
if(String.valueOf(code).equals("S")){ //SK
mSplashDialog.setContentView(R.layout.launch_screen_sk);
}
if(String.valueOf(code).equals("D")){ //D
mSplashDialog.setContentView(R.layout.launch_screen_d);
}
if(String.valueOf(code).equals("B")){ //Beaver
mSplashDialog.setContentView(R.layout.launch_screen);
}
mSplashDialog.setCancelable(false);
if (fullScreen) {
setActivityAndroidP(mSplashDialog);
}
if (!mSplashDialog.isShowing()) {
mSplashDialog.show();
}
}
}
});
}

/**
* 打开启动屏
*/
public static void show(final Activity activity, final boolean fullScreen,final String code) {
int resourceId = fullScreen ? R.style.SplashScreen_Fullscreen : R.style.SplashScreen_SplashTheme;


show(activity, resourceId, fullScreen, code);
}

/**
* 打开启动屏
*/
public static void show(final Activity activity,final String code) {
show(activity, false,code);
}


/**
* 关闭启动屏
*/
public static void hide(Activity activity) {
if (activity == null) {
if (mActivity == null) {
return;
}
activity = mActivity.get();
}

if (activity == null) return;

final Activity _activity = activity;

_activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (mSplashDialog != null && mSplashDialog.isShowing()) {
boolean isDestroyed = false;

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
isDestroyed = _activity.isDestroyed();
}

if (!_activity.isFinishing() && !isDestroyed) {
mSplashDialog.dismiss();
}
mSplashDialog = null;
}
}
});
}

private static void setActivityAndroidP(Dialog dialog) {
//设置全屏展示
if (Build.VERSION.SDK_INT >= 28) {
if (dialog != null && dialog.getWindow() != null) {
dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);//全屏显示
WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();
lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
dialog.getWindow().setAttributes(lp);
}
}
}
}

 

 

해당 java 중 show function 을 수정했다.

 

기본 앱이 react native 이기때문에, 안드로이드와 가장 가볍게 쓸수있는 데이터 저장소를 SharedPreference 로 정하고,

 

api 로 받아온 스플래시 스크린의 구분자를 SharedPreference 로 저장해주고,

 

해당 값에 따라

 

SharedPreferences sharedPreferences = getSharedPreferences("splash", 0);
String result = sharedPreferences.getString("splash", "");

SplashScreen.show(this,result);

 

show 해주는 식으로 작성했다.

 

서버에서 데이터 값을 받아와서 브릿지를 통해 안드로이드의 SharedPreference에 저장하는 방법은

 

const updateSplashCode = React.useCallback(() => {
RNSharedPreferences.getString('splash', 'splash', (result) => {
if (result !== SPLASH_CODE) {
RNSharedPreferences.putString(
'splash',
'splash',
SPLASH_CODE,
// eslint-disable-next-line @typescript-eslint/no-empty-function
(_result) => {},
);
}
});
}, [SPLASH_CODE]);

 

해당 방법으로 해결했으며

 

android 의 sharedPreference 에 접근하는 방법은

 

RNHaredPreferencesPagkage.java

 

package com.bw_frontend_table_order_app.sharedPreference;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.bridge.JavaScriptModule;

public class RNSharedPreferencesPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(new RNSharedPreferencesModule(reactContext));
}

@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}

 

RNSharedPreferencesModul.java

 

package com.bw_frontend_table_order_app.sharedPreference;

import android.content.SharedPreferences;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;

public class RNSharedPreferencesModule extends ReactContextBaseJavaModule {

private final ReactApplicationContext reactContext;

public RNSharedPreferencesModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
}

@Override
public String getName() {
return "RNSharedPreferences";
}

@ReactMethod
public void getString(String prefName, String keyName, Callback resultCallback) {
SharedPreferences sharedPreferences = this.reactContext.getSharedPreferences(prefName, 0);

String result = sharedPreferences.getString(keyName, "");
resultCallback.invoke(result);
}

@ReactMethod
public void putString(String prefName, String keyName, String value, Callback resultCallback) {
SharedPreferences sharedPreferences = this.reactContext.getSharedPreferences(prefName, 0);

boolean commitResult = sharedPreferences.edit().putString(keyName, value).commit();
resultCallback.invoke(commitResult);
}
}

 

로 작성했고

 

const { RNSharedPreferences } = NativeModules;

 

로 해결했다.

728x90
반응형
728x90
반응형

 

 

yarn add @react-native-seoul/kakao-login

 

사이드 프로젝트에 카카오 로그인을 붙이는데

 

[!] CDN: trunk URL couldn't be downloaded: https://cdn.jsdelivr.net/cocoa/Specs/a/d/6/KakaoSDKCommon/2.22.1/KakaoSDKCommon.podspec.json Response: SSL peer certificate or SSH remote key was not OK

 

해당 에러가 나왔다.

찾아보니, vpn을 사용하라는 디투어가있었는데...해당 방법은 적합한것 같지않아서

 

다른 방법을 찾았다.

 

pod file 상단에

 

 

를 추가해주고,

 

podfile.lock 을 삭제해준다.

 

터미널에서

root/ios 로 이동하여

 

pod repo remove trunk

 

로 레포를 제거하고

 

pod install

 

로 다시 깔아주면

 

잘 해결된다.

728x90
반응형
728x90
반응형

현재 redux로 앱내의 상태를 관리하는데,

react-query 를 이용하여, 클라이언트 / 서버의 상태를 분리하기위해 이번에 react-query 를 도입하려한다.

 

const {data, isSuccess, isError} = useQuery(['get-main-info'], () => getMain);

 

해당 코드로 query 를 사용하려하니

 

해당 에러가 나왔다. 

 

에러를 읽어보면 reqct-query v5부터는 object type으로 변경되었다고하는데

 

const {data, isSuccess, isError} = useQuery({
    queryKey: ['get-main-info'],
    queryFn: getMain,
  });

 

같은 내용을 해당 코드로 변경해서 해결했다.

728x90
반응형
728x90
반응형

rn을 하다보면, 기본적인 틀을 짤때 하는 일들이 있다.

 

1.stack navigation / bottom tab navigation

2.redux toolkit

3.persist-store

4.eslint / prettier 설정

 

등등...

만든 템플릿 프로젝트에 들어가있는 라이브러리들

 

사실 프로젝트를 시작할때, 기본적인 구조를 고민하면서 짜는건 즐거운 순간이지만, 대부분 고민을 하고나서 짜는 구조는 비슷해보인다.

 

해서, 시간이 날때 기본적인 라이브러리들을 넣고, 폴더 구조를 잡아 놓은 프로젝트를 만들었다.

 

이번에 새로 시작하는 프로젝트에 해당 프로젝트의 이름만 변경하여 이용하려고한다.

 

그러기위해서는 일단, 프로젝트의 이름 / 번들 id 등을 변경해줘야한다.

 

그러기 위해서는

npm install -g react-native-rename

 

명령어로, react-native-rename 라이브러리를 설치해준다.

 

또 기존 템플릿에서 브랜치도 하나 따준다(혹시 문제가 생길경우를 대비하여, 나는 작업할때 모두 브랜치를 딴다)

 

git checkout -b rename

 

후에, 해당 브랜치의 로컬에서 

 

react-native-rename "새로운이름"

 

명령어를 쳐주면, 

 

파일들이 변경된다.

 

루트에서 

 

npx pod-install

 

로 다시 pod 세팅을 해주면 ios 는 모두 변경이 완료된다.

 

안드로이드 같은 경우에는

 

기존 번들 아이디를 검색하여, 새로운 번들아이디를 입력하면되고, xcode에서도 같은 번들아이디로 변경해주면 끝난다.

 

해당 브랜치의 루트에서

rm -rf ./.git

 

로 깃파일을 없애주고

 

git init

 

으로 새로운 깃을 만들어 레파지토리에 연결해주면 끝이다.

728x90
반응형
728x90
반응형

querydsl를 사용하는 프로젝트를 git clone 해서 돌렸더니,

QClass 들이 import 가 안되는 문제가 발생했다.

 

이때는

 

프로젝트 -> 우클릭 -> Open Module Setting 에서

 

 

해당 java 를 apply 해서 해결했다.

728x90
반응형
728x90
반응형

springboot 프로젝트를 받고나서 돌려볼일이 생겼다.

 

RN 개발자로만 살아온 내게는 배울수 있는 좋은 기회였다.

 

RN 프로젝트는 프로젝트를 받고나서, npm install 이나 yarn 으로 package.jon 에 있는 라이브러리들을 설치해 주어야한다.

 

springboot 도 메이븐을 통해 pom.xml 에 디펜던시들이 세팅되어있다고 알아서 뭔가 그런 세팅을 할줄 알았다.

 

처음 깃에서 클론을 받고, intellij 로 구동해보니

 

Error : unresolved plugin maven

 

해당 에러가 떠있었다.

 

일단

brew install mvn

 

으로 mvn을 설치해주었다.

 

RN 기준으로 이것이, yarn 이나 npm install 을 안한 상태구나라고 어림짐작하고 pom.xml을 설치해 주어야겠다고 생각하고

mvn clean install

 

이라는 명령어를 쳤다.

 

( 하지만 mvn clean install 은 컴파일된 .target 폴더를 지워주는 역할을 했고, install은 빌드하여 jar 파일을 컴파일 해주는 명령어였다. )

 

빌드중에 

 

Error : service: Fatal error compiling: error: release version 19 not supported

 

에러를 만났다. 이는 java version 이 맞지않는 상태에서 나는 에러로 알고

 

5. Mvn -version

해당 자바버전을 확인했다. 프로젝트는 19버전이었기에

 

 

인텔리제이의 File -> Project Structure 에서

 

 

19버전의 java를 다운받고

 

project structure의 project 에서

19버전으로 세팅해줬다.

 

19버전을 세팅하는 것만으로

 

root/src/main/java/SpringframeworkApplication.java

 

에서

 

java 파일을 돌리는것으로 해결했다.

728x90
반응형
728x90
반응형

깃 레파지토리를 옮길때, 두가지 방법이 있다.

1.commit  유지하지않는방법

2.commit / branch 를 유지하는 방법

 

당연히 2번이 훨씬더 편한다.

해당 레파지토리의 .git 파일을 삭제하고, 

 

git init 으로 새로 등록하여 git push 를 하면 끝나기때문이다.

 

하지만, 후임자와 팀원들을 위해 commit 내용을 공유해주어야 할 필요가 있다.

 

만약 해당깃에 

 

100mb 가 넘는 파일이 없는 경우

 

터미널에서

1. git clone --bare {복사하고자하는저장소의 git 주소, 원래 소스코드가 있는 레파지토리}

2. cd {복사하고자하는저장소의git 주소}
3. git push --mirror {붙여놓을저장소의git주소}

 

만 하면 끝난다.

 

하지만, 100mb 가 넘는경우, 해당 프로세스를 진행하면 100mb 가 넘는 파일이 있기때문에 에러가 난다.

 

해결하기 위해서는

1. 100mb 이상의 파일처리

brew install git-lfs  

brew install bfg        

를 먼저깔아주고

 

1. git clone --bare {복사하고자하는저장소의 git 주소, 원래 소스코드가 있는 레파지토리}

2. cd {복사하고자하는저장소의git 주소}

3. git filter-branch --tree-filter 'git lfs track "*.{zip,jar}"' -- --all  

4. brew install bfg 로 깔지않고 jar 파일을 받았을때,  bfg의 위치를 넣은 path 

 

java -jar {bfg의 위치를 넣은 path } --convert-to-git-lfs '*.zip'

java -jar {bfg의 위치를 넣은 path } --convert-to-git-lfs '*.jar'

 

5. git push --mirror {붙여놓을저장소의git주소}

 

하면 끝

728x90
반응형
728x90
반응형

요즘 IOS 앱을 심사 넣을때 메일로 연락이 온다.

해당 내용은 현재 23년 3월 21일에는 문제가 없지만,

starting May 1, 2024, 

24년 5월 1일부터는 새로 앱을 올리거나, 업데이트를 하게되면 문제가 된다는 내용이다.

해당 내용은 이렇다.

 

해당 링크로 이동해서 해석해보면 업데이트된 애플의 개인정보 정책에 대해서 앱내에 명시를 해줘야한다 로 요약할수 있다.

그러면 해당 api들을 추가해보자

 

 

일단 xcode에서 새 파일을 만든다.

 

 

app privacy 파일을 만든다.

 

메일로 온 api 의 코드 종류를 알아보겠다

 

NSPrivacyAccessedAPICategoryDiskSpace

  • 85F4.1장치를 사용하는 사람에게 디스크 공간 정보 표시(표시만 가능, 장치 외부로 보내는 정보는 포함되지 않음)
  • E174.1파일을 쓸 수 있을 만큼 디스크 공간이 충분한지 확인하거나, 디스크 공간이 부족할 때 앱이 파일을 삭제할 수 있도록 디스크 공간이 부족한지 확인하세요.
  • 7D9E.1버그 보고서에 사용됩니다. 단, 제출 여부는 사용자가 선택하는 선택정보이어야 합니다.
  • B728.1건강 연구    API 카테고리에 액세스하여 연구 데이터 수집에 영향을 미치는 디스크 공간 부족에 대해 연구 참여자에게 감지하고 알립니다.

NSPrivacyAccessedAPICategorySystemBootTime

  • 35F9.1앱 내에서 발생한 이벤트 사이에 경과된 시간을 측정하거나 타이머 활성화 계산을 수행하기 위해 시스템 부팅 시간에 액세스합니다. 이 데이터를 이 장치 밖으로 보낼 수 없습니다.
  • 8FFB.1 UIKit 또는 AVFAudio 프레임워크와 관련된 이벤트와 같이 앱 내에서 발생한 이벤트에 대한 절대 타임스탬프를 계산합니다.
  • 3D61.1그 사람이 제출하기로 선택한 버그 보고서에서. 시스템 부팅 시간 정보는 보고서의 일부로 사람에게 눈에 띄게 표시되어야 합니다.

NSPrivacyAccessedAPICategoryFileTimestamp

  • DDA9.1장치를 사용하는 사람에게 파일 타임스탬프를 표시하려고 합니다.
    • 참고: 이러한 이유를 선언하면 정보가 기기 외부로 전송되지 않을 수 있습니다.
  • C617.1앱 컨테이너, 앱 그룹 컨테이너 또는 앱의 CloudKit 컨테이너 내부에 있는 파일의 타임스탬프, 크기 또는 기타 메타데이터에 액세스하세요.
  • 3B52.1문서 선택기 보기 컨트롤러를 사용하는 등 사용자가 특별히 액세스 권한을 부여한 파일이나 디렉터리의 타임스탬프, 크기 또는 기타 메타데이터에 액세스합니다.
  • 0A2A.1타사 SDK가 앱에서 사용할 파일 타임스탬프 API에 대한 래퍼 함수를 제공하고 앱이 래퍼 함수를 호출할 때만 파일 타임스탬프 API에 액세스하는 경우 이 이유를 선언하세요.

요약하자면,

3B52.1  시스템 기본 파일 선택기를 사용하여 사용자가 선택한 파일만 읽는 경우에  사용하세요  . 

DDA9.1 정보를 표시하기만 하고 정보를 저장하거나 업로드하지 않는 경우에 사용하세요  .

C617.1 , 그룹 또는 CloudKit 내에서 정보에 액세스하고 사용하는 경우 사용하세요  .

 

NSPrivacyAccessedAPICategoryUserDefaults

  • CA92.1액세스 사용자는 기본적으로 앱 자체에서만 액세스할 수 있는 정보를 읽고 쓸 수 있습니다.
    • 참고: 이 코드를 선언하면 앱 그룹 내에서 UserDefaults 값을 공유할 수 없습니다(앱과 위젯 간에 데이터를 공유할 수 없음).
  • 1C8F.1액세스 사용자는 기본적으로 앱 자체와 동일한 앱 그룹의 구성원인 앱, 앱 확장 프로그램 및 앱 클립에만 액세스할 수 있는 정보를 읽고 씁니다.
  • C56D.1타사 SDK는 앱이 사용할 사용자 기본 API에 대한 래퍼 기능을 제공하며, 앱이 래퍼 함수를 호출할 때만 사용자 기본 API에 액세스합니다.
    • 참고: 이러한 이유로 액세스된 정보 또는 파생된 정보는 타사 SDK의 자체 목적으로 사용되거나 타사 SDK에 의해 장치 외부로 전송될 수 없습니다.
    • 예를 들어,  앱이 UserDefaults 사용하여 기본 iOS 앱과 위젯 사이에 1C8F.1 사용해야 하는지 여부를 표시하기 위해 사용자의 현재 도시를 공유하는 경우

 

해당 코드를 읽어보고 하나하나씩 본인에 맞는 것으로 선택하면된다.

 

reason을 추가할때, 충분한 설명이 나와있다.

 

설명서를 잘읽고,

구글 analytics 와 sentry가 앱내 붙어있는것을 감안하여, 이유들을 등록하였다. 

최종은

 

이다.

 

해당 privacyInfo 파일을 추가해서 전송하니, 더이상 

Missing API declaration

에 해당하는 메일이 오지않았다.

 

저번주에 ios로 이커머스를 서비스할때, eu 정책이 바뀌어서, 세금관련 정보를 추가했는데, 이번주에는 개인정보 정책을 업로드했다.

 

항상 개발자 메일을 잘 확인해야한다.

 

 

참고링크

https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api

 

728x90
반응형
728x90
반응형
$ yarn add --dev eslint-plugin-prettier
$ yarn add --dev eslint-config-prettier

 

해당 명령어로 eslint 를 설정해주고

 

생성되어있는

 

.eslint.json을

 

{
"parser": "@typescript-eslint/parser",
"plugins": ["react", "@typescript-eslint"],
"extends": [
"eslint:recommended",
"@react-native-community",
"airbnb",
"airbnb/hooks",
"plugin:prettier/recommended"
],
"rules": {
"@typescript-eslint/explicit-module-boundary-types": "off",
"prettier/prettier": ["error", { "endOfLine": "auto" }],
"react/react-in-jsx-scope": "off"
},
"settings": {
"react": {
"version": "detect"
}
},
"env": {
"browser": true,
"node": true
},
"globals": {
"__DEV__": true
}
}

 

로 변경해주고 vscode 를 재시작 하면 된다.

 

아래 옵션은 'React' must be in scope when using JSX 라는 워닝이 나올때 꺼주면, 모든 컴포넌트에서

 

import react from 'React'를 사용할 필요가 없다.

 

"react/react-in-jsx-scope": "off"

728x90
반응형

+ Recent posts