[RN 4-2 프로젝트 개발]
2020. 2. 24. 23:47ㆍReact Native/React Native 날씨 앱
반응형
현재 위치 정보를 가져와 해당 위치의 날씨와 온도를 표시
1) Weather API : Fetch API 사용해서 앱 외부의 날씨 데이터 가지고 오는 API
(*) 회원가입 필수 - 가입 후 발송된 이메일 확인 후 인증
https://openweathermap.org/api
2) 위치 정보 : react-native-geolocation-service 라이브러리
npm install -save react-native-geolocation-service
https://github.com/Agontuk/react-native-geolocation-service
3) 사용자 권한 설정 (안드로이드)
./android/app/src/main/
AndroidManifest.xml 수정
더보기
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.weatherapp">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:name=".MainApplication"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:allowBackup="false"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>
</manifest>
4) WeatherView 컴포넌트
./src/Screens/WeatherView/
index.tsx
(*) API_KEY 는 메일로부터 받은 본인의 것을 입력
더보기
import React, {useEffect, useState} from 'react';
import {FlatList, Alert} from 'react-native';
import Geolocation from 'react-native-geolocation-service';
import Styled from 'styled-components/native';
const Container = Styled.SafeAreaView`
flex: 1;
background-color: #EEE;
`;
const WeatherContainer = Styled(FlatList)``;
const LoadingView = Styled.View`
flex: 1;
justify-content: center;
align-items: center;
`;
const Loading = Styled.ActivityIndicator`
margin-bottom: 16px;
`;
const LoadingLabel = Styled.Text`
font-size: 16px;
`;
const WeatherItemContainer = Styled.View`
height: 100%;
justify-content: center;
align-items: center;
`;
const Weather = Styled.Text`
margin-bottom: 16px;
font-size: 24px;
font-weight: bold;
`;
const Temperature = Styled.Text`
font-size: 16px;
`;
interface Props {}
const API_KEY = '73bd07d674cc4569f650bad6f22dc79d';
interface IWeather {
temperature?: number;
weather?: string;
isLoading: boolean;
}
const WeatherView = ({}: Props) => {
const [weatherInfo, setWeatherInfo] = useState<IWeather>({
temperature: undefined,
weather: undefined,
isLoading: false,
});
const getCurrentWeather = () => {
setWeatherInfo({
isLoading: false,
});
Geolocation.getCurrentPosition(
position => {
const {latitude, longitude} = position.coords;
fetch(
`http://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&APPID=${API_KEY}&units=metric`,
)
.then(response => response.json())
.then(json => {
setWeatherInfo({
temperature: json.main.temp,
weather: json.weather[0].main,
isLoading: true,
});
})
.catch(error => {
setWeatherInfo({
isLoading: true,
});
showError('날씨 정보를 가져오는데 실패하였습니다.');
});
},
error => {
setWeatherInfo({
isLoading: true,
});
showError('위치 정보를 가져오는데 실패하였습니다.');
},
);
};
const showError = (message: string): void => {
setTimeout(() => {
Alert.alert(message);
}, 500);
};
useEffect(() => {
getCurrentWeather();
}, []);
let data = [];
const {isLoading, weather, temperature} = weatherInfo;
if (weather && temperature) {
data.push(weatherInfo);
}
return (
<Container>
<WeatherContainer
onRefresh={() => getCurrentWeather()}
refreshing={!isLoading}
data={data}
keyExtractor={(item, index) => {
return `Weather-${index}`;
}}
ListEmptyComponent={
<LoadingView>
<Loading size="large" color="#1976D2" />
<LoadingLabel>Loading...</LoadingLabel>
</LoadingView>
}
renderItem={({item, index}) => (
<WeatherItemContainer>
<Weather>{(item as IWeather).weather}</Weather>
<Temperature>({(item as IWeather).temperature}°C)</Temperature>
</WeatherItemContainer>
)}
contentContainerStyle={{flex: 1}}
/>
</Container>
);
};
export default WeatherView;
5) App 컴포넌트
더보기
import React from 'react';
import Styled from 'styled-components/native';
import WeatherView from '~/Screens/WeatherView';
const Container = Styled.View`
flex: 1;
background-color: #EEE;
`;
interface Props {}
const App = ({ }: Props) => {
return (
<Container>
<WeatherView />
</Container>
);
};
export default App;
안드로이드 에뮬레이터 위치 허용 : Settings - Location - Allow
(*) 안드로이드 에뮬레이터에서 위치 허용 기능이 정상적으로 동작하지 않으면, 직접 안드로이드 단말로 테스트할 것
반응형
'React Native > React Native 날씨 앱' 카테고리의 다른 글
[RN 4-1 프로젝트 준비] (0) | 2020.02.24 |
---|