Skip to main content 홈 크리에이터 thebushidocollective han expo-modules
expo-modules Use when working with Expo SDK modules for camera, location, notifications, file system, and other device APIs. Covers permissions, configurations, and best practices.
설치로 이동 Skills Marketplace 커뮤니티가 만든 AI 스킬을 발견하고 탐색하세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/TheBushidoCollective/han --skill expo-modules명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
Zip 다운로드 다운로드 중... name expo-modules user-invocable false description Use when working with Expo SDK modules for camera, location, notifications, file system, and other device APIs. Covers permissions, configurations, and best practices. allowed-tools ["Read","Write","Edit","Bash","Grep","Glob"]
Expo Modules
Use this skill when working with Expo's extensive SDK modules for accessing device features and native functionality.
Key Concepts
Camera
import { Camera , CameraType } from 'expo-camera' ;
import { useState } from 'react' ;
import { Button , View } from 'react-native' ;
export default function CameraScreen ( ) {
const [permission, requestPermission] = Camera . ();
[ , setType] = ( . );
(!permission?. ) {
(
);
}
(
);
}
useCameraPermissions
const
type
useState
CameraType
back
if
granted
return
<View >
<Button title ="Grant Permission" onPress ={requestPermission} />
</View >
return
<Camera style ={{ flex: 1 }} type ={type} >
<Button
title ="Flip Camera"
onPress ={() =>
setType(type === CameraType.back ? CameraType.front : CameraType.back)
}
/>
</Camera >
Location import * as Location from 'expo-location' ;
import { useEffect, useState } from 'react' ;
export function useLocation ( ) {
const [location, setLocation] = useState<Location .LocationObject | null >(null );
useEffect (() => {
(async () => {
const { status } = await Location .requestForegroundPermissionsAsync ();
if (status !== 'granted' ) return ;
const loc = await Location .getCurrentPositionAsync ({});
setLocation (loc);
})();
}, []);
return location;
}
Notifications import * as Notifications from 'expo-notifications' ;
import { useEffect } from 'react' ;
Notifications .setNotificationHandler ({
handleNotification : async () => ({
shouldShowAlert : true ,
shouldPlaySound : true ,
shouldSetBadge : false ,
}),
});
export function useNotifications ( ) {
useEffect (() => {
const subscription = Notifications .addNotificationReceivedListener (
(notification ) => {
console .log (notification);
}
);
return () => subscription.remove ();
}, []);
const sendNotification = async ( ) => {
await Notifications .scheduleNotificationAsync ({
content : {
title : 'Hello!' ,
body : 'This is a notification' ,
},
trigger : { seconds : 2 },
});
};
return { sendNotification };
}
File System import * as FileSystem from 'expo-file-system' ;
export async function saveFile (data : string , filename : string ) {
const uri = `${FileSystem.documentDirectory} ${filename} ` ;
await FileSystem .writeAsStringAsync (uri, data);
return uri;
}
export async function readFile (filename : string ) {
const uri = `${FileSystem.documentDirectory} ${filename} ` ;
const content = await FileSystem .readAsStringAsync (uri);
return content;
}
export async function downloadFile (url : string , filename : string ) {
const uri = `${FileSystem.documentDirectory} ${filename} ` ;
const download = await FileSystem .downloadAsync (url, uri);
return download.uri ;
}
Image Picker import * as ImagePicker from 'expo-image-picker' ;
import { useState } from 'react' ;
import { Button , Image , View } from 'react-native' ;
export default function ImagePickerScreen ( ) {
const [image, setImage] = useState<string | null >(null );
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 );
}
};
return (
<View >
<Button title ="Pick Image" onPress ={pickImage} />
{image && <Image source ={{ uri: image }} style ={{ width: 200 , height: 200 }} /> }
</View >
);
}
Best Practices
Permission Handling import * as Location from 'expo-location' ;
async function requestLocationPermission ( ) {
const { status : foregroundStatus } =
await Location .requestForegroundPermissionsAsync ();
if (foregroundStatus !== 'granted' ) {
console .log ('Permission denied' );
return false ;
}
const { status : backgroundStatus } =
await Location .requestBackgroundPermissionsAsync ();
return backgroundStatus === 'granted' ;
}
Secure Storage import * as SecureStore from 'expo-secure-store' ;
export async function saveToken (key : string , value : string ) {
await SecureStore .setItemAsync (key, value);
}
export async function getToken (key : string ) {
return await SecureStore .getItemAsync (key);
}
export async function deleteToken (key : string ) {
await SecureStore .deleteItemAsync (key);
}
Device Info import * as Device from 'expo-device' ;
import * as Application from 'expo-application' ;
import Constants from 'expo-constants' ;
export function getDeviceInfo ( ) {
return {
deviceName : Device .deviceName ,
deviceType : Device .deviceType ,
osName : Device .osName ,
osVersion : Device .osVersion ,
appVersion : Application .nativeApplicationVersion ,
buildVersion : Application .nativeBuildVersion ,
expoVersion : Constants .expoVersion ,
};
}
Common Patterns
Persistent Storage import AsyncStorage from '@react-native-async-storage/async-storage' ;
export const storage = {
async set (key : string , value : any ) {
await AsyncStorage .setItem (key, JSON .stringify (value));
},
async get<T>(key : string ): Promise <T | null > {
const item = await AsyncStorage .getItem (key);
return item ? JSON .parse (item) : null ;
},
async remove (key : string ) {
await AsyncStorage .removeItem (key);
},
async clear ( ) {
await AsyncStorage .clear ();
},
};
Background Tasks import * as BackgroundFetch from 'expo-background-fetch' ;
import * as TaskManager from 'expo-task-manager' ;
const BACKGROUND_FETCH_TASK = 'background-fetch' ;
TaskManager .defineTask (BACKGROUND_FETCH_TASK , async () => {
console .log ('Background task running' );
return BackgroundFetch .BackgroundFetchResult .NewData ;
});
export async function registerBackgroundTask ( ) {
return BackgroundFetch .registerTaskAsync (BACKGROUND_FETCH_TASK , {
minimumInterval : 60 * 15 ,
stopOnTerminate : false ,
startOnBoot : true ,
});
}
Sharing Content import * as Sharing from 'expo-sharing' ;
export async function shareContent (uri : string ) {
const isAvailable = await Sharing .isAvailableAsync ();
if (!isAvailable) {
console .log ('Sharing is not available' );
return ;
}
await Sharing .shareAsync (uri, {
mimeType : 'image/jpeg' ,
dialogTitle : 'Share this image' ,
});
}
Related Skills
expo-config : Configuring module permissions
expo-build : Including modules in builds