월 14,300원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결배달앱 클론코딩 [with React Native]
iOS에서 react-native-vector-icons 설정과정 오류/누락 부분
선생님 강의대로 iOS에 Fonts 그룹을 만들고 node_modules에서 불러오면 아래와 같은 오류를 만나게 됩니다. 폰트를 찾을 수 없다는 것인데 info.plist에 아래 내용을 추가하면 해결됩니다. <key>UIAppFonts</key> <array> <string>AntDesign.ttf</string> <string>Entypo.ttf</string> <string>EvilIcons.ttf</string> <string>Feather.ttf</string> <string>FontAwesome.ttf</string> <string>FontAwesome5_Brands.ttf</string> <string>FontAwesome5_Regular.ttf</string> <string>FontAwesome5_Solid.ttf</string> <string>Fontisto.ttf</string> <string>Foundation.ttf</string> <string>Ionicons.ttf</string> <string>MaterialIcons.ttf</string> <string>MaterialCommunityIcons.ttf</string> <string>SimpleLineIcons.ttf</string> <string>Octicons.ttf</string> <string>Zocial.ttf</string> </array> 아울러, pod install 과정에서 node_modules의 폰트를 불러오는 것 같습니다.(확인은 안 했습니다) 그 결과 Fonts폴더를 만들고 수동으로 폰트를 복사하지 않아도 위와 같은 오류 메시지가 없어짐은 물론, 벡터 아이콘도 정상 출력됩니다.
- 미해결배달앱 클론코딩 [with React Native]
티맵을 Linking.openURL()로 여는 것은 어떤가요?
간단하게 실험해보니 손쉽게 열렸습니다. const goByTMap = useCallback(async () => { const destinationURL = 'tmap://route?goalname=분당서울대병원&goalx=127.122930&goaly=37.351987' if (await Linking.canOpenURL(destinationURL)) await Linking.openURL(destinationURL) }, []) 네이티브 소스를 수정해서 브릿징하는 연습을 해본 것은 너무 좋았습니다. 이런 교육적 의도 말고도 url scheme을 Linking으로 여는 것에 어떤 맹점이 있나요? 가령 url scheme이 변경될 소지가 있더던지? 보안이나 다른 문제가 있을까요?
- 미해결배달앱 클론코딩 [with React Native]
[iOS] RCTTMap.m requiresMainQueueSetup 경고 관련
우여곡절 끝에 티맵 iOS 설정을 마치고 지도가 열리는 걸 보는 기쁨도 잠시 시뮬레이터, 아이폰 모두에서 나타하는 경고가 신경쓰이는군요. 열어보면 다행인지 불행인지 길고 자세한 경고문이 나옵니다. RCTTMap.h를 보면 @interface RCTTMap : NSObject <RCTBridgeModule> RCTBridgeModule을 상속하는 것 같은데 RCTBridgeModule.h을 열어보니 역시나 길고 자세한 설명이 써져 있더군요. /** * Most modules can be used from any thread. All of the modules exported non-sync method will be called on its * methodQueue, and the module will be constructed lazily when its first invoked. Some modules have main need to access * information that's main queue only (e.g. most UIKit classes). Since we don't want to dispatch synchronously to the * main thread to this safely, we construct these modules and export their constants ahead-of-time. * * Note that when set to false, the module constructor will be called from any thread. * * This requirement is currently inferred by checking if the module has a custom initializer or if there's exported * constants. In the future, we'll stop automatically inferring this and instead only rely on this method. */ 대강 해석해보면 비동기 함수를 갖는 경우 등의 이유로 모듈은 아무 쓰레드에서나 작동하는데(자기 methodQueue에서 called되는 게 기본동작), 어떤 모듈은 메인쓰레드(UIKit)의 정보에 접근할 필요가 있다는 것이고, 그럴 때는 requiresMainQueueSetup을 true(YES)로 명시적으로 지시해야 한다.. 지금은 custom init 이 있는지 등을 보고 RN이 유추해주지만 미래엔 유추를 중단할테니 requiresMainQueueSetup을 명시적으로 선언해라... 뭐 그런 내용 같네요. 좋은 내용 같긴 한데.. 티맵 모듈의 경우 만약 우리 배달앱 내에 지도를 랜더링한다면 당연히 메인쓰레드에서 동작하게 해야할텐데, 강의 방향을 보면 단순히 티맵을 열게 호출하는 기능만 하기 때문에 굳이 메인쓰레드여야 할 필요가 없는 것 아닌가 싶기도 합니다. 어떤 쪽이 맞을까요? 단순히 경고만 안 뜨게 하는 것은 쉬웠습니다. RCTTMap.m에 + (BOOL)requiresMainQueueSetup { return YES; } 만 넣어주면 경고도 없어지고 티맵 작동에도 지장이 없습니다. 그런데 문제는! + (BOOL)requiresMainQueueSetup { return NO; } 라고 넣어줘도 경고도 없어지고 티맵도 정상 작동한다는 거죠. openNavi() 메소드는 네이버지도 위 Marker나 Path에 대한 터치 이벤트를 핸들러로 작용하니 당연히 UI가 돌아가는 메인쓰레드에서 호출되도록 고정(return YES)해야만 하고, 백그라운드 쓰레드에서 호출되면(return NO) 오류가 나야 정상일 것 같은데 말이죠. 이유를 설명해주실 수 있나요? 선생님 교안에서도 '메인쓰레드만 쓰도록'이라고 코멘트 해놓으셨는데 - (dispatch_queue_t)methodQueue { // 메인쓰레드만 쓰도록 return dispatch_get_main_queue(); } 이 코드에 대해서도 설명 부탁드립니다.
- 미해결배달앱 클론코딩 [with React Native]
axios.interceptors.response status===419 내에서의 오류처리
안녕하세요 제로초님 엑시오스 인터셉트에서 accessToken이 만료되서 가지고 있던 refreshToken으로 다시 accessToken을 갱신해서 특정 데이터를 다시 요청을 하는데.. 만약 refreshToken 마저 만료되면 에러가 발생할테니 그 부분에서도 에러처리를 해줘야 하는거겠죠? 사소한 질문이지만 .. 답변해주시면 감사하겠습니다.
- 미해결배달앱 클론코딩 [with React Native]
iOS(아이폰)에서 티맵 못 여는 문제 해결
강의대로 하면 아이폰에서 티맵 연동을 위해 Ing.tsx 페이지에서 path나 marker를 클릭했을 때 tmap이 설치되지 않았다는 Alert가 뜹니다. 이 때 xcode 콘솔에 아래와 같은 메시지가 나타납니다. 2022-04-15 13:56:50.123541+0900 FoodDeliveryApp[16779:2877008] -canOpenURL: failed for URL: "tmap:" - error: "This app is not allowed to query for scheme tmap" 2022-04-15 13:56:50.126746+0900 FoodDeliveryApp[16779:2877216] [javascript] { installed: false } -canOpenURL 함수에서 "tmap" URL을 열 수 없다는 에러를 리턴했기 때문으로 보입니다. 따라서 AndroidManifest에 을 넣어준 것과 유사하게 info.plist에 다음과 같이 "tmap" scheme을 넣어주면 tmap을 열 수 있습니다. 에디터에선 이렇게.. xcode에서는 이렇게.. 안드로이드와 마찬가지로 매뉴얼에는 없고 질답을 검색해야 안내해주는군요 ㅋㅋ https://community.openapi.sk.com/t/ios/6565/4 매일 기도하는 마음으로 코딩하니 신실해지는 느낌입니다.
- 해결됨배달앱 클론코딩 [with React Native]
React Navigation 중 Drawer Navigation 방법을 사용하는 방법?
안녕하세요 제로초님 간단하게 Stack이나 Tab 방식이 아닌 Drawer방식을 한번 사용하고자, 다음과 같은 모듈들을 다운로드 받고 코드를 작성하였습니다. npm install @react-navigation/native npm install react-native-screens npm install react-native-safe-area-context npm install @react-navigation/drawer npm install react-native-gesture-handler npm install react-native-reanimated 해당 코드 작성입니다. Drawer가 실행되어 To Do page 또는 Profile page로 이동이 가능하도록 설계하고 싶었습니다. npm run android로 실행을 해보았지만, 다음과 같은 에러가 발생하여, 밑의 링크대로 고쳐보고 다시 시도를 해보았지만, 똑같은 에러가 지속적으로 발생하였습니다. 그리고 스마트폰 화면에는 아무것도 나오지 않았습니다... 관련 에러를 복사하여 구글링을 한 결과 다음과 같은 대답을 찾게 되었고, 그대로 이행해 보았습니다. https://stackoverflow.com/questions/70710318/react-navigation-drawer-giving-me-invariant-violation-module-appregistry-is-not 그리고 난 뒤, android 파일로 가서 ./gradlew clear를 한 뒤, 다시 전 폴더로 돌아가 npm run android를 실행해 보았지만 똑같은 에러를 마주하게 되었습니다... 혹시, 수업 내용에서는 나오지 않았지만 Drawer를 에러없이 이용하기 위해서는 어떤 방법을 사용해야할 지 여쭈어볼 수 있을까요? 감사합니다!
- 미해결배달앱 클론코딩 [with React Native]
axios 0.25 이상에서 multipart/form-data 문제
강의 6분 근처에 이미지 전송 오류 관련해서 0.24로 내리지 않고 0.25이상에서 작동하기는 한다네요. https://github.com/axios/axios/issues/4406#issuecomment-1048693170 axios.post(url, formData, { headers: { 'Content-Type': 'multipart/form-data' }, transformRequest: formData => formData, }) 이런 식으로 하면 작동하는군요. 0.26에서 확인했습니다. 흠... 불편하네요. https://github.com/axios/axios/issues/4406#issuecomment-1066677603 한달 전에 수정한다고 코멘트했는데 아직도 반영은 안된듯 싶습니다. 0.24로 내렸다가 반영되면 올리는 게 제일 나은 것 같습니다.
- 미해결배달앱 클론코딩 [with React Native]
input rendering 관련 질문드립니다.
안녕하세요 회원 가입 폼을 만들어보다 궁금한 점이 생겨서 질문드립니다. 회원 가입 할때 많은 정보가 필요해서 그만큼 TextInput을 넣었습니다. 근데 이를 onChangeText Event를 통해서 userInfo라는 store에 계속해서 set을 했습니다. 기능은 문제 없이 돌아가지만, 생각해보니까 유저가 입력할 때마다 계속해서 전체가 리렌더링이 되는 부분이 마음에 걸려서요. 혹시 이러한 방법이 정상적일 가요? 하나 생각해본거는 모든 input의 ref 값을 최종 회원가입 버튼 때 target value로 가져와서 한번만 store에 set을 하면 어떨까라는 생각도 해봤어요. 혹시 어떤게 맞는건지 혹은 더 좋은 방법이 있는지에 대해서 궁금합니다.
- 미해결배달앱 클론코딩 [with React Native]
혹시 안드로이드 세팅 안되시는 분들 참고하시길 바랍니다!
우선 티맵 설치 안되시는 분들은 우측 설정 창 (전원, 볼륨, 가로모드, 세로모드, 카메라 등등) 에서 ...<- 요거 클릭하시고 왼쪽에 Google Play 눌르셔서 업데이트 진행하시고 다시 Tmap 설치하시면 정상적으로 설치되구요 티맵에서 libs 폴더에 jar파일 넣을 때 빨간 색으로 뜨시는 분들은 jar파일을 다른 에디터가 아닌 안드로이드 스튜디오에서 직접 libs폴더 생성 후 넣으시고 진행하시면 문제없이 작동합니다!
- 미해결배달앱 클론코딩 [with React Native]
navigate 파라미터(데이터) 전달 질문있습니다.
안녕하세요. navigate 간 파라미터를 통해 데이터를 전달하려고 하는데, 계속 애러가 나오고, 해결할 감이 잘 안오네요... 몇 시간동안 검색해봤지만, 찾기가 어려워 이렇게 문의하게 되었습니다. MainVote에서 ->stackVote로 navigation.navigate('stackVote',params) 이동하면서 params에 데이터를 넣어주려는데 애러가 계속 납니다.
- 미해결배달앱 클론코딩 [with React Native]
FlatList 기능 문의합니다.
안녕하세요. FlatList로 기능을 구현하다가. 반복 후, 마지막에 뭔하는 <View>를 넣는 방법을 찾다가 글을 올리게 되었습니다. 구글에 검색을 해도, 특정 기능을 지칭하는 단어가 떠오르지않아 구체적인 검색이 잘 안되서 문의하게 됬습니다. <FlatList/> 로 반복 후, 마지막 부분만 제가 원하는 Component를 추가하고 싶은데, 좋은 방법이 있을까요? 추가로 사진처럼 가로로 스크롤을 하다가, 손을 놨을 때, 특정 위치로 자동으로 움직이는(돌아가는) 기능이 FlatList에서 구현이 가능할까요?
- 해결됨배달앱 클론코딩 [with React Native]
jwt 토큰 질문있습니다!
안녕하세요. 제로초님 강좌에서는 로컬 로그인시 jwt를 이용하여 인증을 해주고 있잖아요? 그런데 만약 로컬로그인이 아니라 소셜로그인 할때는 어떻게 해야할지 궁금해서 질문드립니다. 강좌에서는 로컬로그인을 할때 로그인 하면 jwt토큰을 이용하여 email정보를 가지고 sign하고accessToken과 refreshToken을 발급받고 다른 api요청시 토큰 유효성 검사를 해주면서 토큰 인증을 해주었잖아요? 그런데 만약 카카오 같은 소셜로그인을 했을 시, 소셜로그인에서는 로그인하면 카카오에서 발급해준 email과 accesstoken과 refreshtoken을 리턴값으로 주더라구요? 이때 소셜로그인에서는 카카오에서 발급해준 accesstoken과 refreshtoken을 사용하지 않고 강좌와 같은 플로우와 로직으로 카카오에서 발급해준 email, kakao id 값이나다른 정보를 백에서 jwt를 이용하여 accesstoken과 refreshToken 을 발급받고 강좌와 같은 플로우와 로직을 따르면 되는건가요?(jwt sign, intercepter, verifyToken, verifyRefreshToken등같은 강좌와 같은 로직 ) 아니면 백은 건들지 않고 프론트에서 카카오에서 발급해준 accessToken과 refreshToken으로 유효성검사를 해주며 jwt를 사용하지 말아야 하는지, 강좌와 다른 플로우를 만들어야 하는지 궁금합니다!!!
- 미해결배달앱 클론코딩 [with React Native]
안녕하세요 다이나믹하게 foreground 알림 조절 관련 질문드립니다.
안녕하세요. <meta-data android:name="com.dieam.reactnativepushnotification.notification_foreground" android:value="true"/> 이 부분에서 react native 단에서 토글로 끄고 키면서 저 값을 다이나믹하게 이용할 수 있을까요?
- 미해결배달앱 클론코딩 [with React Native]
accessToken redux 저장관련 질문드립니다.
안녕하세요. 강의를 듣다 궁금한 점이 생겨 질문 남깁니다. accessToken을 redux에 주로 저장을 하신다고 했는데요. 만약에 앱을 껐다가 키면 accessToken이 날아가고 그렇게 되면 사용자가 다시 로그인을 해야되는 상황이 일어나지 않을까라는 생각이 들어서요. 혹시 날라갔을 때는 그때마다 refresh 토큰으로 대체 시키는 건가요? 이 부분이 궁금합니다!
- 미해결배달앱 클론코딩 [with React Native]
가로 스크롤이 궁금합니다.
안녕하세요. 가로 스크롤을 구현해야 하는 상황입니다. scrollView에 horizontal=true로 구글에서 찾아서 쓰려고 하는 하는데, 성능에 큰 영향을 준다고 하셔서, 혹시 좋은 방법이 있는지 공유가 가능할까요?
- 미해결배달앱 클론코딩 [with React Native]
안녕하세요 try catch 관련해서 질문드려요
강의를 듣다가 자바스크립트에서 try catch 를 사용하면 안좋다고 하는데 그 이유가 뭘까요?
- 해결됨배달앱 클론코딩 [with React Native]
푸시알림에 관하여 질문있습니다!
안녕하세요 제로초님 fcm푸시알림에 대하여 질문있습니다. 강좌에서 푸시알림을 보내면 백그라운드 작업표시줄에만 푸시 알림이 오잖아요? 이런식으로요 그런데 저는 이런식으로 알림이 오게 하고싶습니다. 카톡이나 쿠팡 다른 앱들의 푸시알림은 이렇게 통일 되어서 오더라구요? 그래서 로컬 notification이랑 합쳐서 사용해봤더니 전혀 다른 디자인의 알림이 왔습니다. 그래서 이방법은 아닌것 같았구요. 구글에 검색해보니 저렇게 오게 하려면 push permission을 받아야 한대서 react-native-permissions 라이브러리에 서 찾아보니 안드로이드는 push notification을 받을 수 없다고 나오더라구요... 구글에 검색한 결과 의견이 다 다르게 나와 무엇이 맞는것인지 잘모르겠습니다. 혹시 백그라운드에서 저렇게 카톡이나 쿠팡알림 처럼 알림이 오게하려면 어떤것을 사용해야하나요?
- 해결됨배달앱 클론코딩 [with React Native]
토큰 질문있습니다!
제로초님 저번에 강좌에서 낸 숙제라고 하신 앱을 킬때마다 리프레시 토큰 갱신하는것을 구현해 보았습니다. 그런데 제가 옳은 방법으로 했는지 피드백 부탁드립니다!! 질문 1. 로그인을 해서 accesstoken과 refreshtoken을 이미 발급받았고 앱을 껐다가 다시 켰을 때를 가정했을 시 getTokenAndRefresh 함수가 실행되어 (1)의 axios.post(`${Config.API_URL}/refreshToken`,백앤드 요청이 갑니다. AppInner.tsx useEffect(() => { const getTokenAndRefresh = async () => { try { const token = await EncryptedStorage.getItem('refreshToken'); if (!token) { return; } const response = await axios.post( ////////////(1) `${Config.API_URL}/refreshToken`, {}, { headers: { authorization: `Bearer ${token}`, }, }, ); dispatch( userSlice.actions.setUser({ name: response.data.data.name, email: response.data.data.email, accessToken: response.data.data.accessToken, }), ); await EncryptedStorage.setItem( (3) ////////추가된 부분 'refreshToken', response.data.data.refreshToken, ); } catch (error) { console.error(error); if ((error as AxiosError).response?.data.code === 'expired') { // refreshToken 만료되었을 때 Alert.alert('알림', '다시 로그인 해주세요.'); } } }; getTokenAndRefresh(); }, [dispatch]); app.js의 백앤드에서 리프레시 토큰 유효성 검사를 한 후 (2) refreshtoken(새로 추가한 부분)와 accesstoken을 같이 발급해 줍니다. 그러면 다시 AppInner 프론트 페이지로 가서 accesstoken을 리덕스에 저장하고 refreshtoken은1은(2의) await EncryptedStorage.setItem에 저장해줍니다. app.js (백앤드) app.post("/refreshToken", verifyRefreshToken, (req, res, next) => { const refreshToken = jwt.sign( // (2) 추가된 부분 { sub: "refresh", email: res.locals.email }, jwtSecret, { expiresIn: "24h" } ); const accessToken = jwt.sign( { sub: "access", email: res.locals.email }, jwtSecret, { expiresIn: "5m" } ); if (!users[res.locals.email]) { return res.status(404).json({ message: "가입되지 않은 회원입니다." }); } res.json({ data: { accessToken, refreshToken, // 추가된 부분 email: res.locals.email, name: users[res.locals.email].name, }, }); }); 이렇게 구현해 보았는데요. 결과는 로그인 하면 기존처럼 accesstoken과 refreshtoken이 발급되고 앱을 껐다가 키면 리프레시 토큰 유효성 검사를 한 뒤 유효하면 accesstoken과 refreshtoken을 다시 발급해주며 갱신시켜 줍니다. 만약 refreshotken이 만료되었다면 로그인 페이지로 이동하게 되구요. 시도를 해보니 잘 작동을 하는것 같은데 혹시 제가 무엇을 빼놓지는 않았는지 옳은방법으로 한것인지 제로초님의 의견이 궁금합니다!. 질문2. 강의중 제로초님은 accesstoken은 리덕스에 refreshtoken은 암호 저장소에 저장한다고 하셨는데 그러면 백엔드 db에는 둘 중 어느 토큰도 저장하지 않으시는지 궁금합니다. 만약 그렇다면 로그인 할때 백엔드에서 app.post("/login", (req, res, next) => { const refreshToken = jwt.sign( { sub: "refresh", email: req.body.email }, jwtSecret, { expiresIn: "24h" } ); const accessToken = jwt.sign( { sub: "access", email: req.body.email }, jwtSecret, { expiresIn: "5m" } ); users[req.body.email].refreshToken = refreshToken; /////// 이 부분 return res.json({ data: { name: users[req.body.email].name, email: req.body.email, refreshToken, accessToken, }, }); }); users[req.body.email].refreshToken = refreshToken;이 코드가 의미하는바가 무엇인지 궁금합니다. 디비용 더미 데이터 같은데 지웠는데도 잘 실행되더라구요. 없어도 되는 코드인가요?...
- 해결됨배달앱 클론코딩 [with React Native]
질문있습니다!
안녕하세요 제로초님! 위치정보 카메라 권한 얻기 강의에서 질문1. if (Platform.OS === 'android') { check(PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION) .then(result => { console.log('check location', result); if (result === RESULTS.BLOCKED || result === RESULTS.DENIED) { Alert.alert( '이 앱은 위치 권한 허용이 필요합니다', '앱 설정 화면을 열어서 항상 허용으로 바꿔주세요.', [ { text: '네', onPress: () => Linking.openSettings(), }, { text: '아니오', onPress: () => console.log('No Pressed'), style: 'cancel', }, ], ); } }) 위치 권한 허용할 때 위치권한은 항상허용이 사라져서 수동으로 해야한다고 말씀하셨잖아요? 그런데 19:20초쯤 안드로이드에서는 그냥 deny일때 request하면 된다고 하셔서 헷갈리는게 있습니다! 19:20초에서 말씀하신 뜻이 수동으로 말고 request로 해도 된다는 말씀이신가요? 코드에서는 위치권한을 아예 수동으로 설정해놓으셨는데 위치권한 항상허용은 수동으로 해야하나요?... 아니면 deny일때 request를 하면 항상허용이 적용되는 것인가요? 질문2. 또한 deny와 block의 차이를 모르겠습니다. 콘솔로 찍어서 deny와 다른 선택지를 클릭하면 deny는 나오는데 block은 나오지 않습니다 block은 차단인것 같은데 어떨 때 발생하는것인지 궁금합니다.
- 미해결배달앱 클론코딩 [with React Native]
아이폰 개발 하시는 분들 강의 따라해도 연결 안되시는 분들 해결 방법 알려드릴게요!
제로초님께서 말씀 하신대로 10.0.2.2 연결 안되구요. 아이폰 시뮬레이터 와이파이로 연결 시 로컬 호스트로 연결 안됩니다. 따라서 아래 방법 처럼 맥북에서 ip 찾는 법 알려드리겠습니다! 강의에서는 내 ip 찾기 라고 검색하라고 하셨는데, 정확하게 찾으려면 시스템 환경 설정 > 네트워크 > 와이파이 들어가시면 아래와 같이 떠있을 것 입니다. Wi-Fi이(가) [여러분 이름]에 연결되었고 IP 주소는 [여러분 ip 주소]입니다. 여기서 ip 주소를 .env에 넣어주시면 됩니다! API_URL = http://[여러분 IP 주소]:3105