728x90
반응형

 

 

 
 

 

https://developer.android.com/reference/android/Manifest.permission

 

Manifest.permission  |  Android Developers

android.inputmethodservice

developer.android.com

해당 내용에 따르면

 

안드로이드는 sdk버전 33 부터 앨범 퍼미션이

 

READ_EXTERNAL_STORAGE

 

에서

READ_MEDIA_IMAGES
READ_MEDIA_VIDEOS

 

등으로 바뀐다.

 

따라서 react-native-permissions 를 사용할때, Platform 의 구분뿐만아니라, 안드로이드의 버전에 따라서도 체크를 해줘야한다.

 

 

728x90
반응형
728x90
반응형

디버그 모드일때는 자연스럽게 작동하던 kakao / google Oauth 는 release 모드 (내부테스트 / 구글스토어)에서 오류가 나곤한다.

 

그때 카카오톡의 오류 메세지는

이고

 

구글의 오류 메세지는 'DEVELOPER_ERROR'

 

이다.

 

이는 SHA1을 구글 / 카카오 개발센터에 등록하지 않았을때 발생하는데, 

 

firebase 에는

 

./gradlew signingReport 를 통해 얻은

 

release / debug sha1 키를 등록해줘야하고

구글 플레이콘솔을 통해 얻은 sha1 키도 등록해줘야한다.

 

이러면 안드로이드의 구글로그인은 완료가 되며

 

https://developers.kakao.com/docs/latest/ko/android/getting-started

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

 

해당 카카오 개발자센터를 참고하여

 

debug / release / 구글 sha1 를 base64로 인코딩하면된다.

 

개발자 센터에 이렇게 sha256키 1개 / sha1 키 3개씩이 등록되면된다.

 

여기서 구글 sha1키를 인코딩하는 명령어는

 

echo "여기에 sha1키를 따옴표 제거하고 붙여넣기" | xxd -r -p | openssl base64 

 

이러면 구글 / 카카오 로그인이 개발 / 릴리즈 / 구글스토어 에서 모두 정상 작동한다.

728x90
반응형
728x90
반응형

일단 해당 작업을 완료하기위해, 백엔드에서 pg 사와 연동이 되어있는 uri 이 필요하다.

 

안드로이드에서

 

boolean java.lang.boolean.booleanvalue()

 

해당 에러때문에 애를 먹었다.

 

일단

 
import SendIntentAndroid from 'react-native-send-intent';

 

해당 npm 에 들어가서 깔아준다.

 

최근 RN 은

compile 을 쓰지않기에

 

로 수정해주고

 

settings.gradle 도 추가하지않았다.

 

MainApplication.java

 

에서도

 

import com.burnweb.rnsendintent.RNSendIntentPackage;

 

임포트만 해주고

 

 

패키지에 따로 추가해주지않았다.

 

<WebView
style={{ flex: 1, width: deviceWidth, height: deviceHeight }}
javaScriptEnabled
javaScriptCanOpenWindowsAutomatically={true}
onShouldStartLoadWithRequest={(event) => {
return onShouldStartLoadWithRequest(event);
}}
setSupportMultipleWindows={false}
source={{ uri: webUrl }}
onError={(err) => console.log('webview ERROR:::', err)}
onMessage={onComplete}
originWhitelist={['*']}
scalesPageToFit={true}
textZoom={100}
/>

 

해당 webview 의 소스코드이다.

 

const onShouldStartLoadWithRequest = useCallback((event) => {
if (event.url.indexOf('wowcomplete') > -1) {
onComplete();
return false;
}
if (
event.url.startsWith('http://') ||
event.url.startsWith('https://') ||
event.url.startsWith('about:blank')
) {
return true;
}
if (Platform.OS === 'android') {
SendIntentAndroid.openAppWithUri(event.url)
.then((isOpened) => {
console.log('isOpened :::::::', isOpened);
})
.catch((err) => {
console.log('openAppWithUri eror ::::', err);
});
return false;
} else {
Linking.openURL(event.url).catch((err) => {
// Alert.alert(
// '앱 실행에 실패했습니다. 설치가 되어있지 않은 경우 설치하기 버튼을 눌러주세요.',
// );
});
return false;
}
}, []);

 

 

onShouldStartLoadWithRequest

 

함수이다.

 

onShouldStartLoadWithRequest

 

callback은 boolean을 리턴해주고, 

 

해당 boolean으로 로딩전에 콜백을 실행하고 로딩을 더 할지말지를 해주는 함수이다.

 

해당 코드들로 하면 안드로이드에서는 정상작동한다.

 

물론 manifest 에 permission들을 추가해줘야한다.

728x90
반응형
728x90
반응형

 

애니메이션 View들을 어떻게 텀을 두고 플레이할까 고민하다가

animated.View 들의 ref 들을 onLayout 콜백에서 index 값의 텀을 두고 실행하게 했다.

 

해당 컴포넌트 코드

 

import { FlatList, TouchableOpacity, View } from 'react-native';
import { upeIp } from './useIp';
import FastImage from 'react-native-fast-image';
import * as Animatable from 'react-native-animatable';
import { useRef } from 'react';

export const Category = () => {
  const { ip } = upeIp();
  const itemRef = useRef<Animatable.View>({});

  return (
    <View style={{ width: '100%', height: 100 }}>
      <FlatList
        horizontal
        showsHorizontalScrollIndicator={false}
        data={ip}
        keyExtractor={(item) => String(item.ipIdx)}
        renderItem={({ item, index }) => {
          return (
            <TouchableOpacity
              onLayout={() =>
                itemRef.current[index].animate(
                  {
                    0: { scale: 0, rotate: '-90deg' },
                    0.5: { scale: 0.5, rotate: '-60deg' },
                    0.75: { scale: 0.8, rotate: '-45deg' },
                    1: { scale: 1.0, rotate: '0deg' },
                  },
                  index * 1000,
                )
              }
            >
              <Animatable.View
                duration={300}
                ref={(ref) => (itemRef.current[index] = ref)}
                style={{
                  width: 100,
                  height: 100,
                  justifyContent: 'center',
                  alignItems: 'center',
                }}
              >
                <View
                  style={{
                    width: 75,
                    height: 75,
                    borderRadius: 50,
                    justifyContent: 'center',
                    alignItems: 'center',
                    shadowColor: '#000',
                    shadowOffset: { width: 3, height: 3 },
                    shadowOpacity: 0.4,
                    shadowRadius: 5,
                    elevation: 3,
                    backgroundColor: 'white',
                  }}
                >
                  <FastImage
                    source={{ uri: item.iconUrl }}
                    style={{
                      width: 75,
                      height: 75,
                      borderRadius: 50,
                    }}
                  />
                </View>
              </Animatable.View>
            </TouchableOpacity>
          );
        }}
      />
    </View>
  );
};

 

아직 미완성이라 style들을 밖으로 빼지않았다.

728x90
반응형
728x90
반응형
 			<View
              style={{
                width: 100,
                height: 100,
                justifyContent: 'center',
                alignItems: 'center',
              }}
            >
              <View
                style={{
                  width: 75,
                  height: 75,
                  borderRadius: 50,
                  justifyContent: 'center',
                  alignItems: 'center',
                  shadowColor: '#000',
                  shadowOffset: { width: 3, height: 3 },
                  shadowOpacity: 0.4,
                  shadowRadius: 5,
                  elevation: 3,
                }}
              >
                <FastImage
                  source={{ uri: item.iconUrl }}
                  style={{
                    width: 75,
                    height: 75,
                    borderRadius: 50,
                  }}
                />
              </View>
            </View>

 

추후 재사용을 위해 메모

728x90
반응형
728x90
반응형

깃랩에 있는 레퍼지토리를 깃허브로 옮길일이 생겼다.

미러링을 걸어놔서 신경을 안쓰고있었는데,

이틀전부터 미러링이 안되고있었다.

 

원인을 찾아보니, 100mb 이상의 커밋이 발생하여 해당 미러링이 안된것으로 보였다.

 

일단 github 에 새로운 레파지토리를 만들고

 

git clone --mirror [클론할 레포지토리]

 

로 커밋메세지등을 클론했다.

 

그 후에, 

 

https://rtyley.github.io/bfg-repo-cleaner/

 

BFG Repo-Cleaner by rtyley

$ bfg --strip-blobs-bigger-than 100M --replace-text banned.txt repo.git an alternative to git-filter-branch The BFG is a simpler, faster alternative to git-filter-branch for cleansing bad data out of your Git repository history: Removing Crazy Big Files Re

rtyley.github.io

 

링크에서 우측

을 통해 커밋로그를 삭제하는 파일을 받아준다.

 

해당 파일을 클론한 레포지토리의 루트에 위치 시켜주고

 

 

 java -jar bfg-1.14.0.jar --strip-blobs-bigger-than 100M [클론한 레퍼지토리.git]

 

를 통해 100M 이상의 커밋 로그를 삭제해준뒤

 

같은 루트에서 cd [클론한 레퍼지토리.git]

 

을 한후, 

 

git push [옮길 레퍼지토리] -f --mirror

 

를 통해 레퍼지토리로 옮겨줬다.

 

후에 다시 gitlab에서 웹훅을 걸어주었다.

728x90
반응형
728x90
반응형

 

이커머스 앱을 준비하면서 당연히 들어가야할 기능중 하나인 주소지 관리를 개발하면서

 

다음 postcode 를 사용하였다.  rn에서 사용하려면 react-native-webview 라이브러리가 설치되어있어야한다.

 

yarn add @actbase/react-daum-postcode

 

yarn add react-native-webview

 

import Postcode from '@actbase/react-daum-postcode';
<Postcode
style={{
width: '100%',
height: '100%',
}}
onError={(e) => console.log(e)}
jsOptions={{ animation: true }}
onSelected={(data) => {
setPostVisible(false);
setZipcode(String(data?.zonecode));
setAddress(data?.address);
console.log(JSON.stringify(data));
}}
/>

 

이런식으로 사용하면된다.

728x90
반응형
728x90
반응형

프론트에서 직접 스토리지에 접근하는건 별로지만,

 

같이 일하는 서버개발자분이 앱에서 바로 S3에 업로드를 부탁하셨다.

 

워낙 라이브러리가 잘되어있어서 업로드를 하는데

 

error code :AccessControlListNotSupported

error message :The bucket does not allow ACLs

 

이라는 에러가 나왔다.

 

AWS 해당 버킷에 들어가서

 

 

편집을 누른 후

 

활성하하면 해결된다.

728x90
반응형
728x90
반응형

jwt decode 를 할 일이 생겼다.

 

yarn add jwt-decode

 

라이브러리를 사용하거나,

 

const parseJwt = (token) => {
try {
return JSON.parse(atob(token.split('.')[1]));
} catch (e) {
console.log('e :::::', e);
return null;
}
};

 

함수를 사용하면되는데,

 

invalid base64 for part #2 (Property 'atob' doesn't exist)

 

라는 에러가 나왔다.

 

app.tsx에서

 

import { decode, encode } from 'base-64';

if (!global.btoa) {
global.btoa = encode;
}

if (!global.atob) {
global.atob = decode;
}
 

 

로 atob / btoa 를 선언해주면 끝

728x90
반응형
728x90
반응형

RN을 하면서 수만가지의 에러를 만났지만, 아직도 처음보는 상황이 많다.

 

xcode로 빌드시, 빌드는 잘되어 index.js 가 돌기시작하고나서,

다음 화면으로 안나가는 일명 'stuck in splash screen' 형태가 나와서

xcode 를 살펴보니, Running 부분이 Paused로 변경되어있었다.

 

정말 감이 안오는 부분이라, 커뮤니티에 물어봤는데,

해당 부분의 태그를 클릭하여

break point 를 풀어주면 정상작동한다.

728x90
반응형

+ Recent posts