https://docs.expo.dev/versions/latest/sdk/location/
vscode에서 현재 실행중인 터미널은 놔두고
git bash로 하나 더 열어서 설치한다.
그러면 실행중에도 설치 가능함.
그리고 app.json 에 아래의 플러그인을 추가한다.
{
"expo": {
"plugins": [
[
"expo-location",
{
"locationAlwaysAndWhenInUsePermission": "Allow $(PRODUCT_NAME) to use your location."
}
]
],
"name": "my-app",
"slug": "my-app",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "light",
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
App.js로 돌아가서
expo-location을 import 하고
처음 시작 시 위치정보 가져오게끔 요청을 보낸다.
만약 허용을 하지 않으면 false 로 바꿈
import { StatusBar } from "expo-status-bar";
import { Dimensions, ScrollView, StyleSheet, Text, View } from "react-native";
import * as Location from "expo-location";
import { useEffect, useState } from "react";
//각 스마트폰 화면의 가로 사이즈
const { width: SCREEN_WIDTH } = Dimensions.get("window");
export default function App() {
const [location, setLocation] = useState();
const [ok, setOk] = useState(true);
const ask = async () => {
const { granted } = await Location.requestForegroundPermissionsAsync();
if (!granted) {
setOk(false);
}
};
useEffect(() => {
ask();
}, []);
아래와 같이 뜬다
앱 사용 중에만 허용 클릭
이제 실제로 로케이션 객체에서 위도, 경도를 가져와 위치 정보를 알아내기.
https://docs.expo.dev/versions/latest/sdk/location/
export default function App() {
const [location, setLocation] = useState();
const [ok, setOk] = useState(true);
const ask = async () => {
const { granted } = await Location.requestForegroundPermissionsAsync();
if (!granted) {
setOk(false);
}
//accuracy 5 -> 정확도 5단계 제일 높음
const {
coords: { latitude, longitude },
} = await Location.getCurrentPositionAsync({ accuracy: 5 });
};
import { StatusBar } from "expo-status-bar";
import { Dimensions, ScrollView, StyleSheet, Text, View } from "react-native";
import * as Location from "expo-location";
import { useEffect, useState } from "react";
//각 스마트폰 화면의 가로 사이즈
const { width: SCREEN_WIDTH } = Dimensions.get("window");
export default function App() {
const [location, setLocation] = useState();
const [ok, setOk] = useState(true);
const ask = async () => {
const { granted } = await Location.requestForegroundPermissionsAsync();
if (!granted) {
setOk(false);
}
//경도와 위도 값을 가지고 옴
//accuracy 5 -> 정확도 5단계 제일 높음
const {
coords: { latitude, longitude },
} = await Location.getCurrentPositionAsync({ accuracy: 5 });
// 가지고 온 경도, 위도 값에 맍는 위치를 파악할 수 있는 API사용해서 요청
const location = await Location.reverseGeocodeAsync(
{ latitude, longitude },
{ useGoogleMaps: false }
);
console.log(location);
};
콜솔로 위치를 잘 가져왔는데 확인한다.
콘솔은 터미널에서 확인가능하다
위와 같이 현재 위치가 잘 출력된다.
이것을 state로 저장해서 화면에 보여주면 됨
import { StatusBar } from "expo-status-bar";
import { Dimensions, ScrollView, StyleSheet, Text, View } from "react-native";
import * as Location from "expo-location";
import { useEffect, useState } from "react";
//각 스마트폰 화면의 가로 사이즈
const { width: SCREEN_WIDTH } = Dimensions.get("window");
export default function App() {
const [city, setCity] = useState("Loading...");
const [location, setLocation] = useState();
const [ok, setOk] = useState(true);
const ask = async () => {
const { granted } = await Location.requestForegroundPermissionsAsync(); //위치 정보 사용자 동의 얻기
if (!granted) {
setOk(false);
}
//경도와 위도 값을 가지고 옴
//accuracy 5 -> 정확도 5단계 제일 높음
const {
coords: { latitude, longitude },
} = await Location.getCurrentPositionAsync({ accuracy: 5 });
// 가지고 온 경도, 위도 값에 맍는 위치를 파악할 수 있는 API사용해서 요청
const location = await Location.reverseGeocodeAsync(
{ latitude, longitude },
{ useGoogleMaps: false }
);
console.log(location);
setCity(location[0].city || location[0].district);
};
useEffect(() => {
ask();
}, []);
return (
<View style={styles.container}>
<View style={styles.city}>
<Text style={styles.cityName}>{`${city}`}</Text>
</View>
{/* //스크롤뷰를 가로로 해서 수평으로 스크롤하고 스크롤바를 삭제함. */}
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
style={styles.weather}
>
<View style={styles.day}>
<Text style={styles.temp}>27°</Text>
<Text style={styles.description}>Sunny</Text>
</View>
<View style={styles.day}>
<Text style={styles.temp}>28°</Text>
<Text style={styles.description}>Sunny</Text>
</View>
<View style={styles.day}>
<Text style={styles.temp}>29°</Text>
<Text style={styles.description}>Sunny</Text>
</View>
<View style={styles.day}>
<Text style={styles.temp}>30°</Text>
<Text style={styles.description}>Sunny</Text>
</View>
<View style={styles.day}>
<Text style={styles.temp}>31°</Text>
<Text style={styles.description}>Sunny</Text>
</View>
</ScrollView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#FFF3CF",
},
city: {
flex: 1.2,
justifyContent: "center",
alignItems: "center",
},
cityName: {
fontSize: 68,
fontWeight: "500",
},
weather: {},
day: {
flex: 1,
width: SCREEN_WIDTH,
alignItems: "center",
},
temp: {
marginTop: 50,
fontWeight: "600",
fontSize: 170,
},
description: {
marginTop: -30,
fontSize: 60,
},
});
화면에 서울 -> 부산진구로 출력된다.
지역에 맞는 날씨를 가져오기 위해 오픈웨더 API 서비스를 이용한다.
https://openweathermap.org/forecast16
lat={lat}&lon={lon}
우리가 가져온 위도 경도를 넣어주면 됨.
import { StatusBar } from "expo-status-bar";
import {
ActivityIndicator,
Dimensions,
ScrollView,
StyleSheet,
Text,
View,
} from "react-native";
import * as Location from "expo-location";
import { useEffect, useState } from "react";
//각 스마트폰 화면의 가로 사이즈
const { width: SCREEN_WIDTH } = Dimensions.get("window");
const API_KEY = "784ab24ff2ed5d94d4288abed9e25d13";
export default function App() {
const [city, setCity] = useState("Loading...");
const [days, setDays] = useState([]);
const [location, setLocation] = useState();
const [ok, setOk] = useState(true);
const weather = async () => {
const { granted } = await Location.requestForegroundPermissionsAsync(); //위치 정보 사용자 동의 얻기
if (!granted) {
setOk(false);
}
//경도와 위도 값을 가지고 옴
//accuracy 5 -> 정확도 5단계 제일 높음
const {
coords: { latitude, longitude },
} = await Location.getCurrentPositionAsync({ accuracy: 5 });
// 가지고 온 경도, 위도 값에 맍는 위치를 파악할 수 있는 API사용해서 요청
const location = await Location.reverseGeocodeAsync(
{ latitude, longitude },
{ useGoogleMaps: false }
);
// console.log(location);
setCity(location[0].city || location[0].district); // city값이 null일 경우에은 district가 들어감
const response = await fetch(
`https://api.openweathermap.org/data/2.5/onecall?lat=${latitude}&lon=${longitude}&exclude=alerts&appid=${API_KEY}&units=metric`
);
const json = await response.json();
console.log(json);
setDays(json.daily);
};
useEffect(() => {
weather();
}, []);
return (
<View style={styles.container}>
<View style={styles.city}>
<Text style={styles.cityName}>{`${city}`}</Text>
</View>
{/* //스크롤뷰를 가로로 해서 수평으로 스크롤하고 스크롤바를 삭제함. */}
<ScrollView
pagingEnabled
horizontal
showsHorizontalScrollIndicator={false}
style={styles.weather}
>
{days.length === 0 ? (
<View style={styles.day}>
{/* 없을 경우에는 로딩 표시 */}
<ActivityIndicator
color="white"
style={{ marginTop: 10 }}
size="large"
/>
</View>
) : (
days.map((day, index) => (
<View key={index} style={styles.day}>
<Text style={styles.temp}>
{parseFloat(day.temp.day).toFixed(1)}
</Text>
<Text style={styles.description}>{day.weather[0].main}</Text>
<Text style={styles.tinyText}>{day.weather[0].description}</Text>
</View>
))
)}
</ScrollView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#FFF3CF",
},
city: {
flex: 1.2,
justifyContent: "center",
alignItems: "center",
},
cityName: {
fontSize: 68,
fontWeight: "500",
},
weather: {},
day: {
flex: 1,
width: SCREEN_WIDTH,
alignItems: "center",
},
temp: {
marginTop: 50,
fontWeight: "600",
fontSize: 170,
},
description: {
marginTop: -30,
fontSize: 60,
},
});
https://jsonformatter.curiousconcept.com/#
'FRONTEND > ReactNative' 카테고리의 다른 글
[전기차 충전소 찾기 앱]프로젝트 시작 (0) | 2024.02.06 |
---|---|
[TodoApp] TodoApp만들기 (1) | 2024.02.05 |
[날씨앱] expo 배포용 앱 만들기 (0) | 2024.02.01 |
[날씨앱] ReactNative 규칙 및 가로 스크롤 뷰 사용 (1) | 2024.01.31 |
[expo] 프로젝트 시작하기 , 앱 설치하여 qr연결해서 확인하기 (0) | 2024.01.31 |