Youcef Madadi
Web and game development teacher
Native & React Native
Many apps, many tools but how does it work ?
Mobile App Development involves creating software applications that run on mobile devices.
Mobile apps are crucial for businesses to engage users, provide services, and enhance productivity.
Aspect | Web Development | Mobile Development | Desktop Development |
---|---|---|---|
User Reach | Broad, accessible via any browser | High, large user base on smartphones | Limited, specific to desktop/laptop users |
User Engagement | Moderate, depends on web app functionality | High, frequent use, push notifications | Moderate, depends on application type |
Accessibility | Highly accessible, no installation needed | Accessible with app download, push notifications | Requires installation, less accessible |
Monetization | Ads, subscriptions, in-app purchases | In-app purchases, subscriptions, ads | Purchase price, subscriptions, e-sales |
Marketplaces | Websites, online directories | App stores (App Store, Google Play) | App stores (Microsoft Store, Mac App Store) |
User Preferences | Quick access, multi-device compatibility | Seamless experience, offline capabilities | Powerful features, productivity tools |
Updates | Immediate updates, continuous deployment | Regular updates through app stores | Manual or auto-updates depending on OS |
Performance Expectation | Varies with network speed and browser | High performance expected, optimized for device | High performance expected, leverages system resources |
Aspect | Web Development | Mobile Development | Desktop Development |
---|---|---|---|
Security | SSL/TLS, web security best practices | Platform-specific security, permissions | OS-specific security measures, firewalls |
Cost of Development | Generally lower, faster iterations | Higher, platform-specific skills needed | Moderate to high, depends on complexity |
User Interaction | Forms, mouse, keyboard | Touch, gestures, voice commands | Mouse, keyboard, some voice commands |
Customer Support | Online help, chatbots | In-app support, chat, notifications | Built-in help, dedicated support teams |
Analytics | Web analytics tools (Google Analytics) | Mobile analytics tools (Firebase, Flurry) | Desktop analytics tools, built-in OS analytics |
Brand Loyalty | Lower, users easily switch websites | Higher, app presence on user’s device | Moderate, depends on application necessity |
Offline Functionality | Limited, mostly online | Extensive, many apps work offline | Extensive, desktop apps usually fully functional offline |
Development Speed | Faster prototyping and deployment | Slower, more thorough testing needed | Moderate, varies with complexity and platform |
Currently iOS and Android dominate the mobile OS market.
Android holds a larger global market share, while iOS is predominant in certain regions.
Trends include AI integration, AR/VR, and 5G technology.
Understanding the lifecycle of mobile apps is necessary to build a solid app.
Different states an iOS app can be in during its lifecycle:
Not running, inactive, active, background, suspended
The app is in the foreground but not receiving events (e.g., the user receives a phone call).
The app is not launched or has been terminated by the system or user.
The app is in the foreground and receiving events. This is the normal state for the app when it is running and in use.
The app is in the background and executing code. An app can remain in this state for a short period before being suspended, or longer if it has background tasks.
The app is in the background and not executing code. It remains in memory but does not run any code.
Different states an Android activity can be in during its lifecycle:Created, started, resumed, paused, stopped, destroyed
Called when the activity is first created.
Called when the activity becomes visible to the user
Called when the activity starts interacting with the user.
Called when the system is about to put the activity into the background.
Called when the activity is no longer visible to the user
Called after the activity has been stopped, just before it is started again
Called before the activity is destroyed
React Native provides a lifecycle similar to React for web development but includes additional considerations for mobile app states and interactions.
export default function App() {
useEffect(() => {
const handleAppStateChange = (nextAppState: AppStateStatus) => {
if (nextAppState === 'active') {
// App has come to the foreground
console.log('App is in foreground');
} else if (nextAppState === 'background') {
// App has gone to the background
console.log('App is in background');
} else if (nextAppState === 'inactive') {
// App is in an intermediate state
console.log('App is inactive');
}
};
AppState.addEventListener('change', handleAppStateChange);
return () => {
AppState.removeEventListener('change', handleAppStateChange);
};
}, []);
return ( /* Your component JSX */ );
};
import React, { useEffect } from 'react';
import { AppState, AppStateStatus } from 'react-native';
Each OS has its own components and elements, but we can pick the common ones and see their equivalent in REACT NATIVE.
IOS | Android | REACT NATIVE |
---|---|---|
UIView | View | <View> |
UILabel | TextView | <Text> |
UIButton | Button | <Button> |
UITableView | RecyclerView | <FlatList> |
UICollectionView | ListView | <ScrollView> |
UI components are like building blocks of a house.
Auto Layout, Storyboards, XIBs
XML layouts, ConstraintLayout
Flex box
Navigation is essential in any app, where it allows feedback between the app and its user.
import { Stack } from 'expo-router';
export default function Layout() {
return (
<Stack
screenOptions={{
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}}>
{/* Optionally configure static options outside the route.*/}
<Stack.Screen name="home" options={{}} />
</Stack>
);
}
app/_layout.tsx
export default function Home() {
return (
<View style={styles.container}>
<Stack.Screen
options={{
title: 'My home',
headerStyle: { backgroundColor: '#f4511e' },
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
headerTitle: props => <LogoTitle {...props} />,
}}
/>
<Text>Home Screen</Text>
<Link href={{ pathname: 'details', params: { name: 'Bacon' } }}>Go to Details</Link>
</View>
);
}
app/index.tsx
export default function Details() {
const router = useRouter();
const params = useLocalSearchParams();
return (
<View style={styles.container}>
<Stack.Screen
options={{
title: params.name,
}}
/>
<Text onPress={() => { router.setParams({ name: 'Updated' }); }}>
Update the title
</Text>
</View>
);
}
app/details.tsx
for more details check: Stack - Expo Documentation
API and data are managed with local light databases systems in the OS and can be accessed in different ways.
Core Data, UserDefaults
+
Room, SharedPreferences
AsyncStorage, SQLite
+
expo install @react-native-async-storage/async-storage
import AsyncStorage from '@react-native-async-storage/async-storage';
export default function AsyncStorageExample () {
const [storedData, setStoredData] = useState('');
const storeData = async () => {
try {
await AsyncStorage.setItem('@myStorageKey', 'Hello, AsyncStorage!');
alert('Data stored successfully!');
} catch (e) {
alert('Failed to store data.');
}
};
const retrieveData = async () => {
try {
const value = await AsyncStorage.getItem('@myStorageKey');
if (value !== null) {
setStoredData(value);
} else {
alert('No data found.');
}
} catch (e) {
alert('Failed to retrieve data.');
}
};
};
return (
<View style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}}>
<Text>Stored Data: {storedData}</Text>
<Button title="Store Data" onPress={storeData} />
<Button title="Retrieve Data" onPress={retrieveData} />
</View>
);
Many services in the mobiles systems requires permissions such as cameras, microphone, access files...etc.
Info.plist
AndroidManifest.xml
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted, request it
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CAMERA},
CAMERA_PERMISSION_REQUEST_CODE);
}
let locationManager = CLLocationManager()
locationManager.requestWhenInUseAuthorization()
AVCaptureDevice.requestAccess(for: .video) { (granted: Bool) in
if granted {
// Permission granted, proceed with using the camera
} else {
// Permission denied, handle accordingly
}
}
import { PermissionsAndroid, Platform } from 'react-native';
async function requestCameraPermission() {
if (Platform.OS === 'android') {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA,
{
title: 'Camera Permission',
message: 'App needs access to your camera.',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) console.log('Camera permission granted');
else console.log('Camera permission denied');
} catch (err) {
console.warn(err);
}
} else {
// iOS specific permission handling
// Example using Expo Permissions module:
// const { status } = await Permissions.askAsync(Permissions.CAMERA);
}
}
import { PermissionsAndroid, Platform } from 'react-native';
async function checkLocationPermission() {
if (Platform.OS === 'android') {
try {
const granted = await PermissionsAndroid.check(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION
);
if (granted) {
console.log('Location permission granted');
} else {
console.log('Location permission denied');
}
} catch (err) {
console.warn(err);
}
} else {
// iOS specific permission handling
// Example using Expo Permissions module:
// const { status } = await Permissions.askAsync(Permissions.LOCATION);
}
}
By Youcef Madadi