Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
What good can happen when we tap Allow on the pop-up that asks to access our location? Some apps provide better experience, like Facebook suggesting events nearby. Othersāāācanāt work properly without knowing device location, like Uber or GoogleĀ Maps.
These location-based apps use device location to enable and control some features. From wok delivery to Find My iPhone, location-based apps help us with our everyday tasks just by knowing where weĀ are.
Location can be either the primary function, like in Tinder; or auxiliary, like in Instagram: when uploading a photo, Instagram will suggest you a place so you can tag your location. Whether itās the main function or not, location does improve the user experience.
In this article, Iāll tell you about the main tech components of location-based apps, and youāll learn how to develop one using React Native. First, Iāll briefly describe React Native and compare it to native app development. Then Iāll share approaches to gathering and displaying the location in an app, and finally, in a short passage Iāll describe some of the design challenges and how React Native copes withĀ them.
Tools For Location-Based Application Development: ReactĀ Native
In this part, I will briefly describe the React Native framework, its pros & cons, and why itās great for building location-based apps. React Native is an open source JavaScript framework that allows developers create cross-platform apps with their native behavior.
What is behavior in this description? Let me explain. iOS and Android are differentāāātheir interface is different, their animation is different, lots of things are different. Having the same app for iOS and Android would require developing two separate apps. It used to be a laborious process, but using React Native, developers write one code, and it works correctly on both platforms.
This allows businesses to offer their app to both iOS and Android users which means a bigger market share. Thatās why many companies prefer React Nativeāāāthey canāt afford developing two separate apps or are confident about whether their users have iOS or Android. And considering that the cross-platform market is likely to grow to $80 billion by 2020, it seems a rational choice for startups.
Now, Iāll explain the pros and cons of React Native in terms of developing location-based apps.
React NativeĀ Pros
- Cross-platform. Rather than writing separate code for each system (iOS and Android), you build one to operate them both. Neither do you design different UI andĀ UX.
- High performance. React Native uses native controls and modules. The code interacts with the corresponding native iOS and Android components and renders the code to native APIs. Native API is the focusāāāby using a separate from UI thread, it increases the performance of theĀ app.
- Open source. The React Native community grows every day, and so does the number of open-source components. This allows for sharing the experience among the community members, improving the framework, and finding the solutions to existing bugs. All this combined accelerates the development process.
- It saves money. The three previous points conclude into a considerable advantageāāāReact Native saves your money. Itās faster than building two separate apps and so it takes less time for testing and releasing anĀ MVP.
However, there are cases when you might not want to use ReactĀ Native.
They include:
- You donāt need a cross-platform app. If you know that your audience prefers a particular platform, I suggest you opt for native development. Firstly, the app will be tailored to match the specifics of the OS, and secondly, youāll be able to use platform-specific features, like ARKit forĀ iOS.
- You need more APIs than React Native offers. The one thing I particularly dislike is that React Native has a limited number of supported native APIs. There are enough to build a location-based app, though. In case you need othersāāāyou can bridge them using the nativeĀ code.
How to gather and display userĀ location
This part is about gathering and displaying the location data. Depending on the specifics of your app, you will opt for a particular way.
Gathering locationĀ data
I single out three ways to gather device location.
Note: This is a generic overview for you to understand the cases when to opt for each case and the differences betweenĀ them.
Using React NativeĀ API
Thereās a native JavaScript API that identifies the location of a device. Itās easy to install and use, but thereās a ābutāāāāit neither works on the background nor shows the location provider (3G, Wi-Fi,Ā GPS).
react-native-background-geolocation
Itās a package that determines the location of a device from 0 to 1000 meters (0.6 miles). It takes more battery energy, but on the other hand, itās up to you to configure how often to track the location. The package also integrates with SQLiteāāāyou can store the recorded location data and sync it to your database viaĀ HTTP.
import { NativeModules, DeviceEventEmitter, PermissionsAndroid } from 'react-native' import Config from 'react-native-config' import get from 'lodash/get' const { GeoLocation } = NativeModules
class BackgroundGeoLocation { constructor(token, user_id) { this.state = null } start(dispatch, nextState) { this.dispatch = dispatch const token = get(nextState, 'session.data.token') const user_id = get(nextState, 'user.data.user_id') const id = get(nextState, 'user.data.id') this.state = { user_id, token, }
return PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION) .then(is_granted => is_granted === PermissionsAndroid.RESULTS.GRANTED ? is_granted : PermissionsAndroid.requestMultiple([ PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION, PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION, ]) ) .then(_ => PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION)) .then(is_granted => is_granted === PermissionsAndroid.RESULTS.GRANTED ? true : new Error()) .then(_ => setTimeout(() => GeoLocation.startService(token, user_id, id, `${Config.API_URL}/live/car-tracking/gps-pos/`), 300)) .catch(e => console.log(e)) } stop() { return GeoLocation.stopService() .then(_ => console.log(_)) }
handleLocationChange(geo) { console.log(geo) }}
export default BackgroundGeoLocation
Being a package, it requires regular maintenance and updates, but thereās a support channel on GitHub from the creator of theĀ package.
Note: Package price: iOSāāāfree; Androidāāā$300 for oneĀ app.
Combo: Bridge native code to JavaScript API
The main issue with the first approach (to use native JavaScript API) can be solved by adding native code that will start a foreground service in a separateĀ thread.
package com.djangostars.azyan;
import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.location.Criteria; import android.location.Location; import android.location.LocationManager; import android.os.Build; import android.support.v4.content.ContextCompat;
import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableNativeMap;
/** * Created by AGulchenko on 5/7/18. */
public class GeoLocationModule extends ReactContextBaseJavaModule { public static final String CHANNEL_ID = "ExampleService_Channel"; public GeoLocationModule(ReactApplicationContext reactContext) { super(reactContext); if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel(CHANNEL_ID,"testName", NotificationManager.IMPORTANCE_DEFAULT); NotificationManager manager = reactContext.getSystemService(NotificationManager.class); manager.createNotificationChannel(channel); } }
@Override public String getName() { return "GeoLocation"; }
@ReactMethod public void startService(String token, String user_id, String id, String url_string, Promise promise) { WritableMap result = Arguments.createMap(); result.putString("ststus", "success"); try { Intent serviceIntent = new Intent(getReactApplicationContext(), GeoLocationService.class); serviceIntent.putExtra("token", token); serviceIntent.putExtra("user_id", user_id); serviceIntent.putExtra("id", id); serviceIntent.putExtra("url_string", url_string); getReactApplicationContext().startService(serviceIntent); promise.resolve(result); } catch (Exception e) { e.printStackTrace(); promise.reject("rrrrr",e); return; }
}
@ReactMethod public void stopService(Promise promise) { String result = "Success"; try { Intent serviceIntent = new Intent(getReactApplicationContext(), GeoLocationService.class); getReactApplicationContext().stopService(serviceIntent); } catch (Exception e) { promise.reject(e); return; } promise.resolve(result); }
@ReactMethod public void getLocation( Promise promise) { WritableMap res = Arguments.createMap(); try { LocationManager locationManager = null;
locationManager = (LocationManager) this.getReactApplicationContext().getSystemService(Context.LOCATION_SERVICE); int permissionCheck = ContextCompat.checkSelfPermission(this.getReactApplicationContext(), android.Manifest.permission.ACCESS_FINE_LOCATION); if (permissionCheck == PackageManager.PERMISSION_GRANTED) { Criteria criteria = new Criteria(); String bestProvider = locationManager.getBestProvider(criteria, false); Location location = locationManager.getLastKnownLocation(bestProvider); if(location != null) { res.putDouble("latitude", location.getLatitude()); res.putDouble("longitude", location.getLongitude()); promise.resolve(res); }
} } catch (Exception e) { promise.reject(e); return; } }}
Getting permission to access the location data sometimes causes troubles, but the troubles are bearable. React Native solves the problem without too muchĀ fuss.
Different systems ask for the permission to access the location data on different stages: iOS requests the permission first time you open an app; Androidāāāupon the download. It could cause trouble if we were using the native code, however, React Native simplifies this process using the check access to location data module. It allows access to location data without triggering the permission alert.
Displaying Location
The location data isnāt always precise. You must have seen something likeĀ this:
Hereās why it may happen: the device collects the location data from three sources: Wi-Fi, cellular and GPS, the latter being the least accurate. Our devices are in the constant state of checking if thereās good Internet connection. If thereās none, the device will enable GPS. And if thereās a quick leap from 4G to GPS, the device isĀ ālostā.
To solve this problem, I recommend Fused Location Client by Google. It allows you to set the time and distance at which the location data is updated: for instance, update the data every 50 meters and every 10 seconds. You will avoid the noisy data as this API matches all device locations to roads and sidewalk. However, if the device is far from either, it wonāt be effective.
A Few Words AboutĀ Design
In this short part, I will tell you about obstacles that may arise with building location-based apps and how to solve them with React native components.
React Native allows for simple ways of displaying maps. It UI components for Material Design simplify the job for engineers. We would use Material Design to create a Google Maps wrapper, and then React Native would adjust them to the specific features of each platform.
Infinite List is a React Native feature that makes an endless list of search results. In Uber, if you start typing an address, you will get all the destinations starting with what youāve entered. So try 3rd Ave, it will show all 3rd Aves around. Such lists arenāt really endlessāāāthey just load more results as we scroll down through them. Flat Listāāāanother build-in UI component includes the fixed header, footer, and delimiters to the search. If you were to create such result lists from scratch, it would take you more time than building a complete React nativeĀ app.
<FlatList data={get(props, 'order.data.items', [])} renderItem={listItem} keyExtractor={({ id }) => id} style={style.list} />
function listItem({ item: { quantity, name } }) { return ( <View style={style.main}> <Text style={[style.count, style.listItemText]}>{quantity}</Text> <Text style={[style.listItemText, style.name]}>{name}</Text> </View> )}
Bottom Line
React Native may be the right choice if you are going to build a location-based application. If most of the described advantages are true for you, go do deeper research on the technology and its capabilities.
I now encourage you to pay more attention to the apps you use. Youāll be surprised to find out that most of them ask to allow access to your location. For many companies, itās crucial to know user location to provide quality and more user-oriented service. Why donāt youĀ try?
This article about building a location-based app with react native is written by Julia Korsun. Originally published on Django StarsĀ blog.
If you find this post useful, please tap š button belowĀ :)
Building a Location-based App with React Native was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.