npx create-expo-app my-app | 새 프로젝트 생성 |
npx create-expo-app my-app --template blank-typescript | TypeScript로 |
npx expo start | 개발 서버 시작 |
npx expo start --tunnel | 터널로 시작 |
npx expo start --ios | iOS 시뮬레이터 시작 |
npx expo start --android | Android 에뮬레이터 시작 |
npx expo start --web | 웹 시작 |
npx expo prebuild | 네이티브 프로젝트 생성 |
eas build --platform ios | iOS 빌드 |
eas build --platform android | Android 빌드 |
eas build --platform all | 모든 플랫폼 빌드 |
eas submit --platform ios | App Store 제출 |
eas submit --platform android | Play Store 제출 |
eas update | OTA 업데이트 배포 |
import { StatusBar } from "expo-status-bar";
import { StyleSheet, Text, View } from "react-native";
export default function App() {
return (
<View style={styles.container}>
<Text>Hello Expo!</Text>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
}); import {
View,
Text,
Image,
ScrollView,
TextInput,
TouchableOpacity,
FlatList,
SafeAreaView,
} from "react-native";
function MyComponent() {
return (
<SafeAreaView style={{ flex: 1 }}>
<ScrollView>
<Image
source={{ uri: "https://example.com/image.jpg" }}
style={{ width: 200, height: 200 }}
/>
<TextInput
placeholder="Enter text"
onChangeText={(text) => console.log(text)}
/>
<TouchableOpacity onPress={() => alert("Pressed")}>
<Text>Press me</Text>
</TouchableOpacity>
</ScrollView>
</SafeAreaView>
);
} import * as ImagePicker from "expo-image-picker";
import { Camera } from "expo-camera";
// Request permission
const [permission, requestPermission] = Camera.useCameraPermissions();
// Pick image from library
const pickImage = async () => {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
if (!result.canceled) {
setImage(result.assets[0].uri);
}
};
// Take photo
const takePhoto = async () => {
const result = await ImagePicker.launchCameraAsync({
allowsEditing: true,
});
}; import * as Location from "expo-location";
import * as Notifications from "expo-notifications";
// Get location
const getLocation = async () => {
const { status } = await Location.requestForegroundPermissionsAsync();
if (status !== "granted") return;
const location = await Location.getCurrentPositionAsync({});
console.log(location.coords.latitude, location.coords.longitude);
};
// Schedule notification
const scheduleNotification = async () => {
await Notifications.scheduleNotificationAsync({
content: {
title: "Reminder",
body: "Don't forget!",
},
trigger: { seconds: 60 },
});
}; import AsyncStorage from "@react-native-async-storage/async-storage";
// Store data
const storeData = async (key: string, value: any) => {
await AsyncStorage.setItem(key, JSON.stringify(value));
};
// Get data
const getData = async (key: string) => {
const value = await AsyncStorage.getItem(key);
return value ? JSON.parse(value) : null;
};
// Remove data
const removeData = async (key: string) => {
await AsyncStorage.removeItem(key);
};
// Clear all
const clearAll = async () => {
await AsyncStorage.clear();
}; // app.json
{
"expo": {
"name": "My App",
"slug": "my-app",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/icon.png",
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"ios": {
"bundleIdentifier": "com.example.myapp",
"supportsTablet": true
},
"android": {
"package": "com.example.myapp",
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#ffffff"
}
},
"plugins": [
"expo-camera",
"expo-location"
]
}
}