https://github.com/mr-won/nomadweather
Create Weather information Application by using React-Native (리액트 네이트브로 날씨 정보앱 개발)
https://github.com/mr-won/nomadweather
react-native react-native-app react-native-project
Last synced: 11 months ago
JSON representation
Create Weather information Application by using React-Native (리액트 네이트브로 날씨 정보앱 개발)
- Host: GitHub
- URL: https://github.com/mr-won/nomadweather
- Owner: mr-won
- Created: 2021-11-21T04:09:30.000Z (about 4 years ago)
- Default Branch: master
- Last Pushed: 2021-11-24T07:44:40.000Z (about 4 years ago)
- Last Synced: 2025-03-18T02:27:11.937Z (11 months ago)
- Topics: react-native, react-native-app, react-native-project
- Language: JavaScript
- Homepage:
- Size: 208 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Create Weather information Application by using React-Native (리액트 네이트브로 날씨 정보앱 개발)
## 프로젝트 시작
프로젝트 NomadWeather를 다음 명령으로 실행한다.
```javascript
expo init 프로젝트명
```
다음 명령으로 expo 아이디, 비밀번호를 기입하여 로그인을 시도한다.
```javascript
expo login
```
로그인이 완료되면 다음 명령으로 휴대폰에서 expo 어플리케이션을 통해 시뮬레이터를 작동할 수 있다.
```javascript
npm start
```
## 기본 레이아웃 지정
```javascript
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default function App() {
return (
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "tomato",
},
});
```
## 날씨를 측정할 도시 이름와 기온, 날씨 정보를 생성
### 날씨를 측정할 도시 이름 생성
```javascript
Seoul
```
스타일
```javascript
city:{
flex: 1,
justifyContent: 'center',
alignItems:'center',
},
cityName:{
fontSize: 68,
fontWeight: "500",
},
```
### 기온과 날씨 정보 생성
```javascript
27
Sunny
```
스타일
```javascript
day: {
justifyContent:'center',
alignItems:'center',
},
temp: {
marginTop: 50,
fontSize: 178,
},
desc: {
marginTop: -30,
fontSize: 60,
```
### weather안의 day View를 여러개 생성하고 weather를 ScrollView로 변경
스크롤기능을 제공하는 API인 ScrollView를 Import 해준다.
```javascript
import {ScrollView} from 'react-native'
```
그리고 weather를 ScrollView로 감싸준다.
```javascript
27
Sunny
27
Sunny
27
Sunny
27
Sunny
27
Sunny
27
Sunny
```
스크롤을 수직이 아닌 수평으로 만들어주는 horizontal 속성을 ScrollView에 적용
```javascript
```
#### ScrollView 사용시 생기는 문제점
weather와 day의 flex 값을 삭제한다. (ScrollView가 ScrollView의 Childern보다 커야하기 때문)
```javascript
weather:{
backgroundColor:'blue',
},
day: {
alignItems:'center',
},
```
ScrollView의 style을 contentContainerStyle로 수정한다.
```javascript
```
## Dimensions로 사용자의 디바이스의 크기를 측정
react-native의 Dimensions를 import한다.
```javascript
import {Dimensions} from 'react-native';
```
사용자 디바이스의 가로 너비를 Dimensions의 get 메서드로 구한 뒤 SCREEN_WIDTH에 저장한다.
```javascript
const {width: SCREEN_WIDTH} = Dimensions.get('window');
```
SCREEN_WIDTH를 여러개의 day에 적용한다.
```javascript
day:{
width: SCREEN_WIDTH,
alignItems: 'center',
}
```
#### ScrollView에 pagingEnabled 속성을 추가하여 스크롤의 이동을 제한한다.
```javascript
```
#### ScrollView에 showHorizontalScrollIndicator={false}를 설정하여 Scroll Indicator를 제거
```javascript
```
## 사용자의 위치 정보를 가져오기
다음 명령을 터미널에서 실행하여 expo가 제공하는 위치정보 API를 설치한다.
```javascript
expo install expo-location
```
expo-location에서 제공하는 Location을 import한다.
```javascript
import {Location} from 'expo-location';
```
### 사용자의 권한 요청
개발문서 https://docs.expo.dev/versions/latest/sdk/location/#locationrequestpermissionsasync 의 Usage 탭에서 사용자의 권한을 요청하는 requestPermissionAsync()
#### 위치 정보의 상태를 useState 함수에 저장
```javascript
const [location, setLocation] = useState();
const [ok, setOK] = useState(true);
```
#### 렌더링 된 후 ask 함수를 호출하는 useEffect 함수 생성
```javascript
useEffect(() => {
ask();
}, []);
```
#### ask 함수가 호출되면 앱 사용중에만 위치정보권한을 요청하는 requestForegroundPermissionsAsync() 함수를 호출
```javascript
const ask = async() => {
const { granted } = await Location.requestForegroundPermissionsAsync(); // 앱 사용중에만 위치정보권한을 사용하는 requestForegroundPermissionAsync()
if(!granted) { // 위치정보 권한을 거절하면
setOk(false); // setOk = false 로 설정
}
};
```
## 사용자 위치 정보 획득
#### getCurrentPositionAsync 함수를 사용하여 사용자의 현재 위치에 대한 경도와 위도를 얻기
다음 코드를 실행하여 latitude와 longitude를 얻는다. accuracy는 1 ~ 6의 정확도값을 얻는 속성값이다.
```javascript
const {coords:{latitude, longitude}} = await Location.getCurrentPositionAsync({accuracy: 5});
```
#### reverse Geocoding 사용하기
얻은 사용자 위치의 latitdude와 longitude로 reverse geocoding을 하여 사용자가 위치한 지역의 country, district, isoCountryCode, name, postalCode, region를 가지는 객체를 배열의 형태로 사질 수 있다.
#### reverseGeocodeAsync 함수의 사용에 앞서 Google Platform 에서 Geolocation API key를 발급받는다.
발급받은 키를 다음과 같이 Location.setGoogleApiKey의 매개변수로 전달한다.
```javascript
Location.setGoogleApiKey('발급받은 키(영문자,대문자,숫자로 이루어짐)')
```
API key 설정이 끝나면 reverseGeocodeAsync 함수의 첫번째 매개변수로 얻은 latitude, longitude 값을 넣고 두번째 매개변수로 useGoogleMaps 속성의 값을 false로 설정한다.
```javascript
const location = await Location.reverseGeocodeAsync({latitude, longitude}, {useGoogleMaps: false});
```
useState를 사용하여 city, setCity의 초기화면을 ...Loading 으로 설정한다.
```javascript
const [city, setCity] = useState("...Loading");
```
setCity의 매개변수로 얻은 객체 중 region 값을 location[0].region으로 전달한다.
```javascript
setCity(location[0].region
```
얻은 region 값을 다시 본문의 고정된 city 값을 useState를 사용한 {city}로 전달한다.
```javascript
{city}
```
## 날씨 정보 얻기
https://home.openweathermap.org/api_keys 에서 api를 받아와서 API_KEY에 저장한다.
```javascript
const API_KEY ="발급받은 api키값";
```
https://openweathermap.org/api/one-call-api 에서 API call의 코드를 복사해서 붙여넣고 앞서 얻은 latitude, longitude, API_KEY 값을 넣어준다.
```javascript
const response = await fetch(`https://api.openweathermap.org/data/2.5/onecall?lat=${latitude}&lon=${longitude}&exclude={part}&appid=${API_KEY}`);
```
위의 exclude 속성은 minute, hour alert 등 얻는 값중에 제외할 값을 설정할 수 있는데 이때는 alert를 제외한다.
```javascript
const response = await fetch(`https://api.openweathermap.org/data/2.5/onecall?lat=${latitude}&lon=${longitude}&exclude=alerts&appid=${API_KEY}`);
```
json 변수에 response.json()으로 api에서 얻은 데이터를 저장한다.
```javascript
const json = await response.json();
```
빈 배열 상태인 useState에 날짜 배열정보를 넣고
```javascript
const [days, setDays] = useState([]);
```
날짜 json.daily setDays의 useState에 셋팅한다.
```javascript
setDays(json.daily);
```
기존의 day를 모두 삭제하고 삼항연산자로 days의 배열의 길이가 0 이면 ActivityIndicator 를 사용해 로딩 중 표시를 하고 배열의 길이가 0이 아닐때는 날씨 정보를 보여주도록 변경한다.
```javascript
{days.length === 0 ? (
) : (
days.map((day, index) => (
{new Date(day.dt * 1000).toString().substring(0, 10)}
{parseFloat(day.temp.day).toFixed(1)}
{day.weather[0].main}
{day.weather[0].description}
))
)}
```