Introduction
Hi everyone ππ»ββοΈ! My name is Vedant, and it is time to build another SCADE app! We all love hybrid tech stack when it comes to building cross-platform mobile apps. And then we start having discussions within the team for the possible tech stack to implement the new app idea. But what if the team is not willing to learn any other language?
SCADE solves this problem for us and makes it super easy to code cross-platform mobile apps using the only language Swift. Itβs like developing Android apps using Swift, without coding a single line in Java or Kotlin. In this article, we will explore the map and geolocation apps that use just a few lines of Swift code, to develop using SCADE.
Fusion SDK
Recently, the SCADE team has gone open-source with their breakthrough technology called Fusion libraries. Fusion enables us to invoke the Android APIs using the Scade Fusion SDK. The benefit, is we donβt have to bother about setting up the Android platform-specific stuff in the gradle or anywhere. Even iOS-specific settings are very easy and no further prerequisite is required for the same.
SCADE swift codebase acts as the single source of truth in this case, and Fusion SDK makes it possible. Currently, Fusion SDK provides easy integrations for the Geolocation, Bluetooth, NFC, and Media Player, and many more Fusion libraries are in development by the SCADE developers.
We will now start the development of the FusionLocation app by integrating the Fusion extension in our SCADE project. Navigate to the Package.swift
and add the below code snippet.
dependencies: [
.package(name: "FusionLocation", url: "https://github.com/scade-platform/FusionLocation.git", .branch("main"))
],
targets: [
.target(
name: "GeoLocation",
dependencies: [
.product(name: "FusionLocation", package: "FusionLocation")
],
exclude: ["main.page"],
swiftSettings: [
.unsafeFlags(["-F", SCADE_SDK], .when(platforms: [.macOS, .iOS])),
.unsafeFlags(["-I", "\(SCADE_SDK)/include"], .when(platforms: [.android])),
]
)
]
We also need to provide the location permission in build.yaml for both iOS and Android platforms.
ios:
...
plist:
...
- key: NSLocationAlwaysAndWhenInUseUsageDescription
type: string
value: This app just tracks your location to test FusionLocation
- key: NSLocationWhenInUseUsageDescription
type: string
value: This app just tracks your location to test FusionLocation
...
android:
...
permissions: ["ACCESS_FINE_LOCATION"]
Please note that the Google API key can also be passed as the value of the key google-api-key
in build.yaml
for invoking Google Cloud APIs related to maps and geolocation.
Tracking User Location
FusionLocation has utility methods for performing location updates in the background. We often require background location update operations for various use cases related to mobility and delivery of mobile apps. All we need to do is to initialize the LocationManager
instance, authenticate the instance and call the location update method of the LocationManager
.
// initialize the LocationManager
let locationManager = LocationManager(usage: .always)
// request authorization
locationManager.requestAuthorization()
// start location tracking
locationManager.startUpdatingLocation { location in
print("Location Updated.")
print(location?.coordinate)
}
Get the Distance between two Coordinates
In order to find the distance between two locations, we will call the inbuilt distanceBetween
method and will pass the location value for the from
and to
params.
let mallLocation = Location(latitude: 12.9574292, longitude: 77.6383552)
let parkLocation = Location(latitude: 12.973826, longitude: 77.590591)
let dist = locationManager.distanceBetween(
from: familyMallLocation, to: cubbon_parkLocation)
print("Distance between Mall and the Park:")
print(String(dist))
We will get the output somewhat like this with real-time updates of the user location coordinates and the distance in meters.
Get Bearing distance
Bearing distance is required in various domains like aircraft navigation or land surveying. Fusion makes it very easy to calculate the bearing distance between two coordinates.
// get bearing between from and to
locationManager.bearingBetween(from: from, to: to)
SCADE Map Integration
SCADE provides MapUIControl to integrate the map widget into our mobile app. Letβs start integrating the map into our existing Fusion SCADE app. Navigate to the main.page
and add the below UI widgets.
a.) MapUI Control: Drag the map widget to the page and we will make the map to cover the entire main.page
height and width.
b.) RowViewUI Control: We need RowView to contain a set of buttons horizontally laid at the bottom of the page.
c.) 5 UI Buttons: We will now create 5 buttons horizontally in the RowView, namely Airport and Seaport to mark the location in the map, and the other 3 buttons will be used to set the type of map at runtime.
First, we will define a few location coordinates which will be used throughout the app.
let airport_coordinate = SCDPlatformLocationCoordinate(latitude: 28.556160, longitude: 77.100281)
let seaport_coordinate = SCDPlatformLocationCoordinate(latitude: 13.08441, longitude: 80.2899)
In order to navigate to the defined coordinate region on the map, we use the setRegion
method of the mapWidget
.
func goto(coordinates: SCDPlatformLocationCoordinate) {
self.mapWidget.setRegion(coordinates, latitudinalMeters: 1000, longitudinalMeters: 1000)
}
It takes the coordinates as the input parameter along with the latitudinalMeters
and longitudinalMeters
to display the location for the given width and height of the region. We will call this goto method for the above-defined buttons to navigate to the coordinates on the map.
// Goto Airport location
self.btnAirport.onClick.append(
SCDWidgetsEventHandler { _ in
self.goto(coordinates: self.airport_coordinate)
})
// goto Seaport location
self.btnSeaport.onClick.append(
SCDWidgetsEventHandler { _ in
self.goto(coordinates: self.seaport_coordinate)
})
To show the marker image for the location on the map, we use the map annotations to append the marker image using the SCDWidgetsMapAnnotation
class.
func setPinAsAnnotaton(coordinate: SCDPlatformLocationCoordinate, imagePath: String) {
let svgImage = SCDSvgImage(width: SCDSvgUnit(value: 55), height: SCDSvgUnit(value: 55))
svgImage.xhref = imagePath
let ann = SCDWidgetsMapAnnotation(location: coordinate)
ann.drawing = svgImage
self.mapWidget.annotations.append(ann)
}
We will now call the above utility method and pass the coordinate and image file path as input parameters.
self.setPinAsAnnotaton(coordinate: airport_coordinate, imagePath: "Assets/mpin.png")
iOS
Android
SCADE map widget provides the feature to change the map type to Standard, Satellite, and Hybrid. SCDWidgetsMapType
class has the inbuilt methods for these map types.
func setMapType(_ name: String) {
switch name {
case "btnHybrid":
self.mapWidget.mapType = SCDWidgetsMapType.hybrid
case "btnSatelite":
self.mapWidget.mapType = SCDWidgetsMapType.satellite
case "btnStandard":
self.mapWidget.mapType = SCDWidgetsMapType.standard
default:
print("not covered")
}
}
We will now set the click listeners to the rest of the buttons to change the map type at runtime.
// satellite mode
self.btnSatelite.onClick.append(
SCDWidgetsEventHandler { _ in
self.setMapType("btnSatelite")
})
// Standard mode
self.btnStandard.onClick.append(
SCDWidgetsEventHandler { _ in
self.setMapType("btnStandard")
})
// Hybrid mode
self.btnHybrid.onClick.append(
SCDWidgetsEventHandler { _ in
self.setMapType("btnHybrid")
})
We are now ready to run the app and test if everything is working as expected. Please save the project otherwise the changes wonβt reflect in the app.
iOS
Android
Voila π! It is very easy to integrate SCADE map and Fusion SDK to create an iOS or Android app for all location needs. We donβt have to bother about any native Android/iOS environment setup or anything like that. We call Android APIs directly through Fusion SDK.
It is cool right! You should try FusionLocation in your next app for maps and geolocation π.
Top comments (0)