해결된 질문
작성
·
27
2
확실히 expo 버전으로 프로젝트를 생성하면, 영상처럼 진행이 되지 않습니다 ㅠㅠ
프로젝트 설치 및 실행 과정은 다음과 같습니다.
기종: Android
npx create-expo-app <앱 이름> --template
세 번째(blank) :typescript 선택
npx expo start를 실행
expo 앱에서 QR 코드로 보기
강의와 달리, expo로 빌드하셨다면
npx expo install expo-location를 설치해주신 다음에
useEffect 함수 부분을 다음과 같이 변경해주면 됩니다.
(Expo는 자체 위치 서비스 API를 제공하므로, @react-native-community/geolocation 대신 expo-location을 사용해야 합니다.)
useEffect(() => {
const getLocation = async () => {
try {
// 위치 권한 요청
let { status } = await Location.requestForegroundPermissionsAsync();
if (status !== 'granted') {
setError('위치 권한이 거부되었습니다');
setLoading(false);
return;
}
// 현재 위치 가져오기
let location = await Location.getCurrentPositionAsync({});
const { latitude, longitude } = location.coords;
fetchWeather(latitude, longitude);
} catch (err) {
setError(err.message);
setLoading(false);
}
};
getLocation();
}, []);
다음으로
OpenWeatherMap API는 기본적으로 켈빈 온도를 반환합니다. 따라서 섭씨로 변환하는 코드를 추가해야 합니다.
각자 가져오신 API 값 뒤에 &units=metirc 를 추가해주시면 됩니다.
전체 코드는 다음과 같습니다.
import { StatusBar } from 'expo-status-bar';
import { useEffect, useState } from 'react';
import { ActivityIndicator, Text, View } from 'react-native';
import styled from 'styled-components/native';
import * as Location from 'expo-location';
const Container = styled.View`
align-items: center;
margin-top: 40px;
background-color: #222222;
flex: 1;
`;
const MainTemp = styled.Text`
font-size: 80px;
color: white;
`;
const Addition = styled.View`
background-color: #aeaeae;
width: 150px;
height: 150px;
margin: 15px;
align-items: center;
justify-content: center;
border-radius: 15px;
`;
const App = () => {
const [weatherData, setWeatherData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const getLocation = async () => {
try {
// 위치 권한 요청
let { status } = await Location.requestForegroundPermissionsAsync();
if (status !== 'granted') {
setError('위치 권한이 거부되었습니다');
setLoading(false);
return;
}
let location = await Location.getCurrentPositionAsync({});
const { latitude, longitude } = location.coords;
fetchWeather(latitude, longitude);
} catch (err) {
setError(err.message);
setLoading(false);
}
};
getLocation();
}, []);
const fetchWeather = async (latitude, longitude) => {
try {
const response = await fetch(
`https://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&appid=<<개인 API값>>&units=metric`
);
// <<>>는 지우셔야 합니다.
if (!response.ok) {
throw new Error('Network response was not ok');
}
const data = await response.json();
setWeatherData(data);
} catch (error) {
setError(error.message);
} finally {
setLoading(false);
}
};
if (loading) {
return (
<Container>
<ActivityIndicator size="large" color="#ffffff" />
</Container>
);
}
if (error) {
return (
<Container>
<Text
style={{ color: 'white', fontSize: 20 }}
>{`Error: ${error}`}</Text>
</Container>
);
}
if (!weatherData) {
return (
<Container>
<Text style={{ color: 'white', fontSize: 20 }}>No data available</Text>
</Container>
);
}
const {
main: { temp, feels_like, humidity, temp_max, temp_min },
wind: { speed },
weather,
} = weatherData;
return (
<Container>
<StatusBar />
<Text style={{ fontSize: 20, marginTop: 40, color: 'white' }}>
{weatherData.name}
</Text>
<MainTemp>{Math.round(temp)}℃</MainTemp>
<Text style={{ fontSize: 24, color: 'white' }}>{weather[0].main}</Text>
<View style={{ flexDirection: 'row' }}>
<Addition>
<Text
style={{
color: 'white',
fontSize: 20,
marginTop: -40,
marginBottom: 30,
}}
>
체감 온도
</Text>
<Text style={{ color: 'white', fontSize: 18 }}>
{Math.round(feels_like)}℃
</Text>
</Addition>
<Addition>
<Text
style={{
color: 'white',
fontSize: 20,
marginTop: -40,
marginBottom: 30,
}}
>
습도
</Text>
<Text style={{ color: 'white', fontSize: 18 }}>{humidity}%</Text>
</Addition>
</View>
<View style={{ flexDirection: 'row' }}>
<Addition>
<Text
style={{
color: 'white',
fontSize: 20,
marginTop: -40,
marginBottom: 30,
}}
>
최고/최저 온도
</Text>
<Text style={{ color: 'white', fontSize: 18 }}>
{Math.round(temp_max)}℃/{Math.round(temp_min)}℃
</Text>
</Addition>
<Addition>
<Text
style={{
color: 'white',
fontSize: 20,
marginTop: -40,
marginBottom: 30,
}}
>
풍속
</Text>
<Text style={{ color: 'white', fontSize: 18 }}>{speed} m/s</Text>
</Addition>
</View>
<View></View>
</Container>
);
};
export default App;
답변 1
0
안녕하세요, 인프런 AI 인턴입니다. 오영택님.
Expo를 이용하여 프로젝트를 생성했을 때와 강의에서 다루는 내용 사이에 발생할 수 있는 차이점에 대해 설명해주셔서 감사합니다. React Native와 Expo 환경에서는 약간의 설정 차이가 존재할 수 있어, 이로 인해 혼동이 생길 수 있습니다.
Expo를 사용하면 위치 서비스 관련 API가 더욱 간단하게 제공됩니다. expo-location
모듈을 사용해주셨듯, Expo 환경에서는 @react-native-community/geolocation
대신 expo-location
을 통해 위치 데이터를 관리하는 것이 올바릅니다.
위치 권한 및 위치 데이터 가져오기:
Location.requestForegroundPermissionsAsync()
를 호출하여 앱이 위치 데이터를 얻을 수 있도록 사용자에게 권한을 요청합니다.Location.getCurrentPositionAsync()
를 사용하여 현재 위치를 획득합니다.API를 통한 날씨 데이터 가져오기:
OpenWeatherMap API
를 사용하여 날씨 정보를 받아옵니다. 여기서 주의할 점은 온도를 섭씨(Celcius)로 표시하기 위해 &units=metric
파라미터를 추가해야 한다는 것입니다.아래 링크에서도 비슷한 문제에 대한 토론이 이루어졌으니 도움이 될 것입니다:
오영택님께서 주신 코드와 설명은 많은 다른 사용자 분들께도 유용한 팁이 될 것입니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.