Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Added a native module for getting the user's location #6

Open
wants to merge 3 commits into
base: feat/add-msw-implementation
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ function App() {
background: config.tokens.colors.white,
},
};

return (
<GluestackUIProvider config={config}>
<StatusBar backgroundColor="$trueGray200" barStyle="dark-content" />
Expand Down
7 changes: 6 additions & 1 deletion android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.INTERNET" />

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:name=".MainApplication"
android:label="@string/app_name"
Expand All @@ -21,5 +22,9 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="MyNavigationService"
android:foregroundServiceType="location">
</service>
</application>
</manifest>
19 changes: 19 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,26 @@ module.exports = {
root: ['.'],
alias: {
'@src': './src',
'location-info-package': './modules/location-info-package',
},
extensions: [
'.ios.js',
'.ios.ts',
'.ios.tsx',
'.android.js',
'.android.ts',
'.android.tsx',
'.js',
'.ts',
'.tsx',
'.json',
],
},
],
[
'@babel/plugin-transform-react-jsx',
{
runtime: 'automatic',
},
],
],
Expand Down
25 changes: 19 additions & 6 deletions ios/Podfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
# Resolve react_native_pods.rb with node to allow for hoisting
require Pod::Executable.execute_command('node', ['-p',
'require.resolve(
"react-native/scripts/react_native_pods.rb",
{paths: [process.argv[1]]},
)', __dir__]).strip
# Transform this into a `node_require` generic function:
def node_require(script)
# Resolve script with node to allow for hoisting
require Pod::Executable.execute_command('node', ['-p',
"require.resolve(
'#{script}',
{paths: [process.argv[1]]},
)", __dir__]).strip
end

# Use it to require both react-native's and this package's scripts:
node_require('react-native/scripts/react_native_pods.rb')
node_require('react-native-permissions/scripts/setup.rb')

platform :ios, min_ios_version_supported
prepare_react_native_project!

setup_permissions([
'LocationAccuracy',
'LocationAlways',
'LocationWhenInUse',
])

linkage = ENV['USE_FRAMEWORKS']
if linkage != nil
Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
Expand Down
33 changes: 32 additions & 1 deletion ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,27 @@ PODS:
- hermes-engine (0.74.3):
- hermes-engine/Pre-built (= 0.74.3)
- hermes-engine/Pre-built (0.74.3)
- LocationInfoPackage (0.0.1):
- DoubleConversion
- glog
- hermes-engine
- RCT-Folly (= 2024.01.01.00)
- RCTRequired
- RCTTypeSafety
- React-Codegen
- React-Core
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-NativeModulesApple
- React-RCTFabric
- React-rendererdebug
- React-utils
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- RCT-Folly (2024.01.01.00):
- boost
- DoubleConversion
Expand Down Expand Up @@ -1193,6 +1214,8 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- RNPermissions (4.1.5):
- React-Core
- RNReanimated (3.14.0):
- DoubleConversion
- glog
Expand Down Expand Up @@ -1248,6 +1271,7 @@ DEPENDENCIES:
- fmt (from `../node_modules/react-native/third-party-podspecs/fmt.podspec`)
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
- hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
- LocationInfoPackage (from `../modules/location-info-package`)
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
- RCT-Folly/Fabric (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
- RCTDeprecation (from `../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation`)
Expand Down Expand Up @@ -1301,6 +1325,7 @@ DEPENDENCIES:
- React-utils (from `../node_modules/react-native/ReactCommon/react/utils`)
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
- RNPermissions (from `../node_modules/react-native-permissions`)
- RNReanimated (from `../node_modules/react-native-reanimated`)
- RNScreens (from `../node_modules/react-native-screens`)
- RNSVG (from `../node_modules/react-native-svg`)
Expand All @@ -1324,6 +1349,8 @@ EXTERNAL SOURCES:
hermes-engine:
:podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec"
:tag: hermes-2024-06-28-RNv0.74.3-7bda0c267e76d11b68a585f84cfdd65000babf85
LocationInfoPackage:
:path: "../modules/location-info-package"
RCT-Folly:
:podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec"
RCTDeprecation:
Expand Down Expand Up @@ -1426,6 +1453,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon"
RNGestureHandler:
:path: "../node_modules/react-native-gesture-handler"
RNPermissions:
:path: "../node_modules/react-native-permissions"
RNReanimated:
:path: "../node_modules/react-native-reanimated"
RNScreens:
Expand All @@ -1442,6 +1471,7 @@ SPEC CHECKSUMS:
fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120
glog: fdfdfe5479092de0c4bdbebedd9056951f092c4f
hermes-engine: 1f547997900dd0752dc0cc0ae6dd16173c49e09b
LocationInfoPackage: da160078952dc413de7607cf00f7768c246345dc
RCT-Folly: 02617c592a293bd6d418e0a88ff4ee1f88329b47
RCTDeprecation: 4c7eeb42be0b2e95195563c49be08d0b839d22b4
RCTRequired: d530a0f489699c8500e944fde963102c42dcd0c2
Expand Down Expand Up @@ -1493,12 +1523,13 @@ SPEC CHECKSUMS:
React-utils: a06061b3887c702235d2dac92dacbd93e1ea079e
ReactCommon: f00e436b3925a7ae44dfa294b43ef360fbd8ccc4
RNGestureHandler: 8dbcccada4a7e702e7dec9338c251b1cf393c960
RNPermissions: a4c964f030841f35d918ab3248df9dec9db5f44d
RNReanimated: f4ff116e33e0afc3d127f70efe928847c7c66355
RNScreens: 5aeecbb09aa7285379b6e9f3c8a3c859bb16401c
RNSVG: 07dbd870b0dcdecc99b3a202fa37c8ca163caec2
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
Yoga: 04f1db30bb810187397fa4c37dd1868a27af229c

PODFILE CHECKSUM: 06a42524715b4c9860a9b26b64f0baa3c14247a0
PODFILE CHECKSUM: 1c0f0611e0c51730f5e9464a5ab6ffb6b32b0564

COCOAPODS: 1.15.2
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
4 changes: 3 additions & 1 deletion ios/WeatherApp/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This is needed to get location updates in the background</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string></string>
<string>This is needed to get location updates when in use</string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
Expand Down
17 changes: 17 additions & 0 deletions jest-setup.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import '@testing-library/react-native/extend-expect';
import * as dotenv from 'dotenv';
import 'react-native-gesture-handler/jestSetup';
import mockPermissions from 'react-native-permissions/mock';
import {server} from './src/api/mocks/server';

dotenv.config({path: '.env.test'});
Expand All @@ -10,6 +11,10 @@ jest.mock('react-native-config', () => ({
OPEN_WEATHER_BASE_URL: process.env.OPEN_WEATHER_BASE_URL,
}));

jest.mock('react-native-permissions', () => {
return mockPermissions;
});

// include this section and the NativeAnimatedHelper section for mocking react-native-reanimated
jest.mock('react-native-reanimated', () => {
const Reanimated = require('react-native-reanimated/mock');
Expand All @@ -24,6 +29,18 @@ jest.mock('react-native-reanimated', () => {
// Silence the warning: Animated: `useNativeDriver` is not supported because the native animated module is missing
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');

jest.mock('location-info-package', () => {
return {
getCurrentLocation: jest.fn(() =>
Promise.resolve({
latitude: 123.456,
longitude: -123.456,
}),
),
// Add other methods of LocationInfoModule here and their mock implementations
};
});

beforeAll(() => server.listen());

// Reset any request handlers that we may add during the tests,
Expand Down
49 changes: 49 additions & 0 deletions modules/location-info-package/LocationInfoPackage.podspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# `.podspec` file is like "`package.json`" for iOS CocoaPods packages

require "json"

package = JSON.parse(File.read(File.join(__dir__, "package.json")))

# Detect if new arch is enabled
new_arch_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == '1'

Pod::Spec.new do |s|
s.name = "LocationInfoPackage"
s.version = package["version"]
s.summary = package["description"]
s.description = package["description"]
s.homepage = package["homepage"]
s.license = package["license"]
s.platforms = { :ios => "13.0" }
s.author = package["author"]
s.source = { :git => package["repository"], :tag => "#{s.version}" }

# This is crucial - declare which files will be included in the package (similar to "files" field in `package.json`)
s.source_files = "ios/**/*.{h,m,mm,swift}"

if new_arch_enabled
s.pod_target_xcconfig = {
"DEFINES_MODULE" => "YES",
"SWIFT_OBJC_INTERFACE_HEADER_NAME" => "LocationInfoPackage-Swift.h",
# This is handy when we want to detect if new arch is enabled in Swift code
# and can be used like:
# #if APP_INFO_PACKAGE_NEW_ARCH_ENABLED
# // do sth when new arch is enabled
# #else
# // do sth when old arch is enabled
# #endif
"OTHER_SWIFT_FLAGS" => "-DAPP_INFO_PACKAGE_NEW_ARCH_ENABLED"
}
else
s.pod_target_xcconfig = {
"DEFINES_MODULE" => "YES",
"SWIFT_OBJC_INTERFACE_HEADER_NAME" => "LocationInfoPackage-Swift.h"
}
end

# Install all React Native dependencies (RN >= 0.71 must be used)
#
# check source code for more context
# https://github.com/facebook/react-native/blob/0.71-stable/scripts/react_native_pods.rb#L172#L180
install_modules_dependencies(s)
end
66 changes: 66 additions & 0 deletions modules/location-info-package/android/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
buildscript {
ext.safeExtGet = {prop, fallback ->
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
}

def kotlin_version = safeExtGet('kotlinVersion', '1.6.10') // Mandatory, if you will use Kotlin

repositories {
google()
gradlePluginPortal()
}
dependencies {
classpath("com.android.tools.build:gradle:7.2.1")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version") // Mandatory, if you will use Kotlin
}
}

def isNewArchitectureEnabled() {
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
}

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android' // Mandatory, if you will use Kotlin
if (isNewArchitectureEnabled()) {
apply plugin: "com.facebook.react"
}

android {
compileSdkVersion safeExtGet('compileSdkVersion', 33)

namespace "com.locationinfopackage"

defaultConfig {
minSdkVersion safeExtGet('minSdkVersion', 21)
targetSdkVersion safeExtGet('targetSdkVersion', 33)
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
}

sourceSets {
main {
if (isNewArchitectureEnabled()) {
java.srcDirs += ['src/newarch/java', "${project.buildDir}/generated/source/codegen/java"]
} else {
java.srcDirs += ['src/oldarch/java']
}
}
}
}

repositories {
maven {
url "$projectDir/../node_modules/react-native/android"
}
mavenCentral()
google()
}

apply from: "$projectDir/react-native-helpers.gradle"

dependencies {
if (project.ext.shouldConsumeReactNativeFromMavenCentral()) {
implementation "com.facebook.react:react-android" // Set by the React Native Gradle Plugin
} else {
implementation 'com.facebook.react:react-native:+' // From node_modules
}
}
Loading