diff --git a/README.md b/README.md index 12e06a7..df92db4 100644 --- a/README.md +++ b/README.md @@ -13,59 +13,32 @@ This module is used by [Tradle](https://github.com/tradle) npm install --save react-native-udp ``` -### `iOS` +## Link in the native dependency -* Drag UdpSockets.xcodeproj from node_modules/react-native-udp/ios into your XCode project. - -* Click on the project in XCode, go to Build Phases, then Link Binary With Libraries and add `libUdpSockets.a` +``` +rnpm link react-native-udp +``` ### `Android` -* `android/settings.gradle` - -```gradle -... -include ':react-native-udp' -project(':react-native-udp').projectDir = new File(settingsDir, '../node_modules/react-native-udp/android') -``` -* `android/app/build.gradle` - -```gradle -dependencies { - ... - compile project(':react-native-udp') -} -``` - -* register module (in MainActivity.java) +* Register and load the Native Module in your Main application +([import](examples/rctsockets/android/app/src/main/java/com/rctsockets/MainApplication.java#L11), [getPackages](examples/rctsockets/android/app/src/main/java/com/rctsockets/MainApplication.java#L28)) + * __Note:__ prior to react-native 0.29.2, this should happen in your Main Activity ```java ... -import com.tradle.react.*; // <--- import +import com.tradle.react.UdpSocketsModule; // <--- import // -public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler { +public class MainApplication extends Application implements ReactApplication { ... - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mReactRootView = new ReactRootView(this); - - mReactInstanceManager = ReactInstanceManager.builder() - .setApplication(getApplication()) - .setBundleAssetName("index.android.bundle") - .setJSMainModuleName("index.android") - .addPackage(new MainReactPackage()) - .addPackage(new UdpSocketsModule()) // <- add here - .setUseDeveloperSupport(BuildConfig.DEBUG) - .setInitialLifecycleState(LifecycleState.RESUMED) - .build(); - - mReactRootView.startReactApplication(mReactInstanceManager, "YourProject", null); - - setContentView(mReactRootView); - } + @Override + protected List getPackages() { + return Arrays.asList( + new MainReactPackage(), + new UdpSocketsModule() // <- add here // + ); + } } ``` diff --git a/examples/rctsockets/.buckconfig b/examples/rctsockets/.buckconfig new file mode 100644 index 0000000..934256c --- /dev/null +++ b/examples/rctsockets/.buckconfig @@ -0,0 +1,6 @@ + +[android] + target = Google Inc.:Google APIs:23 + +[maven_repositories] + central = https://repo1.maven.org/maven2 diff --git a/examples/rctsockets/.flowconfig b/examples/rctsockets/.flowconfig index 05cad20..e28e2f5 100644 --- a/examples/rctsockets/.flowconfig +++ b/examples/rctsockets/.flowconfig @@ -1,51 +1,41 @@ [ignore] # We fork some components by platform. -.*/*.web.js .*/*.android.js -# Some modules have their own node_modules with overlap -.*/node_modules/node-haste/.* +# Ignore templates with `@flow` in header +.*/local-cli/generator.* -# Ignore react-tools where there are overlaps, but don't ignore anything that -# react-native relies on -.*/node_modules/react-tools/src/React.js -.*/node_modules/react-tools/src/renderers/shared/event/EventPropagators.js -.*/node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderEventPlugin.js -.*/node_modules/react-tools/src/shared/vendor/core/ExecutionEnvironment.js - -# Ignore commoner tests -.*/node_modules/commoner/test/.* - -# See https://github.com/facebook/flow/issues/442 -.*/react-tools/node_modules/commoner/lib/reader.js - -# Ignore jest -.*/node_modules/jest-cli/.* - -# Ignore Website -.*/website/.* +# Ignore malformed json +.*/node_modules/y18n/test/.*\.json [include] [libs] node_modules/react-native/Libraries/react-native/react-native-interface.js +node_modules/react-native/flow +flow/ [options] module.system=haste +esproposal.class_static_fields=enable +esproposal.class_instance_fields=enable + +experimental.strict_type_args=true + munge_underscores=true module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub' -module.name_mapper='^[./a-zA-Z0-9$_-]+\.png$' -> 'RelativeImageStub' +module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' suppress_type=$FlowIssue suppress_type=$FlowFixMe suppress_type=$FixMe -suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(1[0-7]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) -suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(1[0-7]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)? #[0-9]+ +suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(2[0-7]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) +suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-7]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy [version] -0.17.0 +^0.27.0 diff --git a/examples/rctsockets/.gitignore b/examples/rctsockets/.gitignore new file mode 100644 index 0000000..eb1535e --- /dev/null +++ b/examples/rctsockets/.gitignore @@ -0,0 +1,41 @@ +# OSX +# +.DS_Store + +# Xcode +# +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +*.xccheckout +*.moved-aside +DerivedData +*.hmap +*.ipa +*.xcuserstate +project.xcworkspace + +# Android/IJ +# +*.iml +.idea +.gradle +local.properties + +# node.js +# +node_modules/ +npm-debug.log + +# BUCK +buck-out/ +\.buckd/ +android/app/libs +android/keystores/debug.keystore diff --git a/examples/rctsockets/android/app/BUCK b/examples/rctsockets/android/app/BUCK new file mode 100644 index 0000000..c8d043f --- /dev/null +++ b/examples/rctsockets/android/app/BUCK @@ -0,0 +1,66 @@ +import re + +# To learn about Buck see [Docs](https://buckbuild.com/). +# To run your application with Buck: +# - install Buck +# - `npm start` - to start the packager +# - `cd android` +# - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US` +# - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck +# - `buck install -r android/app` - compile, install and run application +# + +lib_deps = [] +for jarfile in glob(['libs/*.jar']): + name = 'jars__' + re.sub(r'^.*/([^/]+)\.jar$', r'\1', jarfile) + lib_deps.append(':' + name) + prebuilt_jar( + name = name, + binary_jar = jarfile, + ) + +for aarfile in glob(['libs/*.aar']): + name = 'aars__' + re.sub(r'^.*/([^/]+)\.aar$', r'\1', aarfile) + lib_deps.append(':' + name) + android_prebuilt_aar( + name = name, + aar = aarfile, + ) + +android_library( + name = 'all-libs', + exported_deps = lib_deps +) + +android_library( + name = 'app-code', + srcs = glob([ + 'src/main/java/**/*.java', + ]), + deps = [ + ':all-libs', + ':build_config', + ':res', + ], +) + +android_build_config( + name = 'build_config', + package = 'com.rctsockets', +) + +android_resource( + name = 'res', + res = 'src/main/res', + package = 'com.rctsockets', +) + +android_binary( + name = 'app', + package_type = 'debug', + manifest = 'src/main/AndroidManifest.xml', + keystore = '//android/keystores:debug', + deps = [ + ':app-code', + ], +) diff --git a/examples/rctsockets/android/app/build.gradle b/examples/rctsockets/android/app/build.gradle index f6a12d3..0ad5cc5 100644 --- a/examples/rctsockets/android/app/build.gradle +++ b/examples/rctsockets/android/app/build.gradle @@ -1,23 +1,86 @@ apply plugin: "com.android.application" +import com.android.build.OutputFile + /** - * The react.gradle file registers two tasks: bundleDebugJsAndAssets and bundleReleaseJsAndAssets. + * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets + * and bundleReleaseJsAndAssets). * These basically call `react-native bundle` with the correct arguments during the Android build * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the * bundle directly from the development server. Below you can see all the possible configurations * and their defaults. If you decide to add a configuration block, make sure to add it before the - * `apply from: "react.gradle"` line. + * `apply from: "../../node_modules/react-native/react.gradle"` line. + * + * project.ext.react = [ + * // the name of the generated asset file containing your JS bundle + * bundleAssetName: "index.android.bundle", + * + * // the entry file for bundle generation + * entryFile: "index.android.js", + * + * // whether to bundle JS and assets in debug mode + * bundleInDebug: false, + * + * // whether to bundle JS and assets in release mode + * bundleInRelease: true, + * + * // whether to bundle JS and assets in another build variant (if configured). + * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants + * // The configuration property can be in the following formats + * // 'bundleIn${productFlavor}${buildType}' + * // 'bundleIn${buildType}' + * // bundleInFreeDebug: true, + * // bundleInPaidRelease: true, + * // bundleInBeta: true, + * + * // the root of your project, i.e. where "package.json" lives + * root: "../../", + * + * // where to put the JS bundle asset in debug mode + * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", + * + * // where to put the JS bundle asset in release mode + * jsBundleDirRelease: "$buildDir/intermediates/assets/release", + * + * // where to put drawable resources / React Native assets, e.g. the ones you use via + * // require('./image.png')), in debug mode + * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", + * + * // where to put drawable resources / React Native assets, e.g. the ones you use via + * // require('./image.png')), in release mode + * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", + * + * // by default the gradle tasks are skipped if none of the JS files or assets change; this means + * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to + * // date; if you have any other folders that you want to ignore for performance reasons (gradle + * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ + * // for example, you might want to remove it from here. + * inputExcludes: ["android/**", "ios/**"], + * + * // override which node gets called and with what additional arguments + * nodeExecutableAndArgs: ["node"] + * + * // supply additional arguments to the packager + * extraPackagerArgs: [] + * ] */ - project.ext.react = [ - // the name of the generated asset file containing your JS bundle - bundleAssetName: "index.bundle", +apply from: "../../node_modules/react-native/react.gradle" - // the entry file for bundle generation - entryFile: "index.js", -] +/** + * Set this to true to create two separate APKs instead of one: + * - An APK that only works on ARM devices + * - An APK that only works on x86 devices + * The advantage is the size of the APK is reduced by about 4MB. + * Upload all the APKs to the Play Store and people will download + * the correct one based on the CPU architecture of their device. + */ +def enableSeparateBuildPerCPUArchitecture = false -apply from: "react.gradle" +/** + * Run Proguard to shrink the Java bytecode in release builds. + */ +def enableProguardInReleaseBuilds = false android { compileSdkVersion 23 @@ -33,21 +96,45 @@ android { abiFilters "armeabi-v7a", "x86" } } + splits { + abi { + reset() + enable enableSeparateBuildPerCPUArchitecture + universalApk false // If true, also generate a universal APK + include "armeabi-v7a", "x86" + } + } buildTypes { release { - minifyEnabled false // Set this to true to enable Proguard + minifyEnabled enableProguardInReleaseBuilds proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" } } - // needed for https://github.com/square/okio/issues/58 - lintOptions { - warning 'InvalidPackage' + // applicationVariants are e.g. debug, release + applicationVariants.all { variant -> + variant.outputs.each { output -> + // For each separate APK per architecture, set a unique version code as described here: + // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits + def versionCodes = ["armeabi-v7a":1, "x86":2] + def abi = output.getFilter(OutputFile.ABI) + if (abi != null) { // null for the universal-debug, universal-release variants + output.versionCodeOverride = + versionCodes.get(abi) * 1048576 + defaultConfig.versionCode + } + } } } dependencies { + compile project(':react-native-udp') compile fileTree(dir: "libs", include: ["*.jar"]) compile "com.android.support:appcompat-v7:23.0.1" - compile "com.facebook.react:react-native:0.14.+" - compile project(':react-native-udp') + compile "com.facebook.react:react-native:+" // From node_modules +} + +// Run this once to be able to run the application with BUCK +// puts all compile dependencies into folder libs for BUCK to use +task copyDownloadableDepsToLibs(type: Copy) { + from configurations.compile + into 'libs' } diff --git a/examples/rctsockets/android/app/proguard-rules.pro b/examples/rctsockets/android/app/proguard-rules.pro index ffa8c9f..48361a9 100644 --- a/examples/rctsockets/android/app/proguard-rules.pro +++ b/examples/rctsockets/android/app/proguard-rules.pro @@ -26,11 +26,14 @@ # See http://sourceforge.net/p/proguard/bugs/466/ -keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip -keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters +-keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip # Do not strip any method/class that is annotated with @DoNotStrip -keep @com.facebook.proguard.annotations.DoNotStrip class * +-keep @com.facebook.common.internal.DoNotStrip class * -keepclassmembers class * { @com.facebook.proguard.annotations.DoNotStrip *; + @com.facebook.common.internal.DoNotStrip *; } -keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * { @@ -40,17 +43,20 @@ -keep class * extends com.facebook.react.bridge.JavaScriptModule { *; } -keep class * extends com.facebook.react.bridge.NativeModule { *; } +-keepclassmembers,includedescriptorclasses class * { native ; } -keepclassmembers class * { @com.facebook.react.uimanager.UIProp ; } --keepclassmembers class * { @com.facebook.react.uimanager.ReactProp ; } --keepclassmembers class * { @com.facebook.react.uimanager.ReactPropGroup ; } +-keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp ; } +-keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup ; } + +-dontwarn com.facebook.react.** # okhttp -keepattributes Signature -keepattributes *Annotation* --keep class com.squareup.okhttp.** { *; } --keep interface com.squareup.okhttp.** { *; } --dontwarn com.squareup.okhttp.** +-keep class okhttp3.** { *; } +-keep interface okhttp3.** { *; } +-dontwarn okhttp3.** # okio diff --git a/examples/rctsockets/android/app/react.gradle b/examples/rctsockets/android/app/react.gradle deleted file mode 100644 index dc18bb9..0000000 --- a/examples/rctsockets/android/app/react.gradle +++ /dev/null @@ -1,75 +0,0 @@ -def config = project.hasProperty("react") ? project.react : []; - -def bundleAssetName = config.bundleAssetName ?: "index.android.bundle" -def entryFile = config.entryFile ?: "index.android.js" - -// because elvis operator -def elvisFile(thing) { - return thing ? file(thing) : null; -} - -def reactRoot = elvisFile(config.root) ?: file("../../") -def jsBundleDirDebug = elvisFile(config.jsBundleDirDebug) ?: - file("$buildDir/intermediates/assets/debug") -def jsBundleDirRelease = elvisFile(config.jsBundleDirRelease) ?: - file("$buildDir/intermediates/assets/release") -def resourcesDirDebug = elvisFile(config.resourcesDirDebug) ?: - file("$buildDir/intermediates/res/merged/debug") -def resourcesDirRelease = elvisFile(config.resourcesDirRelease) ?: - file("$buildDir/intermediates/res/merged/release") -def inputExcludes = config.inputExcludes ?: ["android/**", "ios/**"] - -def jsBundleFileDebug = file("$jsBundleDirDebug/$bundleAssetName") -def jsBundleFileRelease = file("$jsBundleDirRelease/$bundleAssetName") - -task bundleDebugJsAndAssets(type: Exec) { - // create dirs if they are not there (e.g. the "clean" task just ran) - doFirst { - jsBundleDirDebug.mkdirs() - resourcesDirDebug.mkdirs() - } - - // set up inputs and outputs so gradle can cache the result - inputs.files fileTree(dir: reactRoot, excludes: inputExcludes) - outputs.dir jsBundleDirDebug - outputs.dir resourcesDirDebug - - // set up the call to the react-native cli - workingDir reactRoot - commandLine "react-native", "bundle", "--platform", "android", "--dev", "true", "--entry-file", - entryFile, "--bundle-output", jsBundleFileDebug, "--assets-dest", resourcesDirDebug - - enabled config.bundleInDebug ?: false -} - -task bundleReleaseJsAndAssets(type: Exec) { - // create dirs if they are not there (e.g. the "clean" task just ran) - doFirst { - jsBundleDirRelease.mkdirs() - resourcesDirRelease.mkdirs() - } - - // set up inputs and outputs so gradle can cache the result - inputs.files fileTree(dir: reactRoot, excludes: inputExcludes) - outputs.dir jsBundleDirRelease - outputs.dir resourcesDirRelease - - // set up the call to the react-native cli - workingDir reactRoot - commandLine "react-native", "bundle", "--platform", "android", "--dev", "false", "--entry-file", - entryFile, "--bundle-output", jsBundleFileRelease, "--assets-dest", resourcesDirRelease - - enabled config.bundleInRelease ?: true -} - -gradle.projectsEvaluated { - // hook bundleDebugJsAndAssets into the android build process - bundleDebugJsAndAssets.dependsOn mergeDebugResources - bundleDebugJsAndAssets.dependsOn mergeDebugAssets - processDebugResources.dependsOn bundleDebugJsAndAssets - - // hook bundleReleaseJsAndAssets into the android build process - bundleReleaseJsAndAssets.dependsOn mergeReleaseResources - bundleReleaseJsAndAssets.dependsOn mergeReleaseAssets - processReleaseResources.dependsOn bundleReleaseJsAndAssets -} diff --git a/examples/rctsockets/android/app/src/main/AndroidManifest.xml b/examples/rctsockets/android/app/src/main/AndroidManifest.xml index ecb025e..4773cd8 100644 --- a/examples/rctsockets/android/app/src/main/AndroidManifest.xml +++ b/examples/rctsockets/android/app/src/main/AndroidManifest.xml @@ -1,16 +1,25 @@ + package="com.rctsockets" + android:versionCode="1" + android:versionName="1.0"> + + + + android:label="@string/app_name" + android:configChanges="keyboard|keyboardHidden|orientation|screenSize"> diff --git a/examples/rctsockets/android/app/src/main/java/com/rctsockets/MainActivity.java b/examples/rctsockets/android/app/src/main/java/com/rctsockets/MainActivity.java index 3b4a661..b384e6a 100644 --- a/examples/rctsockets/android/app/src/main/java/com/rctsockets/MainActivity.java +++ b/examples/rctsockets/android/app/src/main/java/com/rctsockets/MainActivity.java @@ -1,81 +1,16 @@ package com.rctsockets; -import android.app.Activity; -import android.os.Bundle; -import android.view.KeyEvent; +import com.facebook.react.ReactActivity; +import com.tradle.react.UdpSocketsModule; -import com.facebook.react.LifecycleState; -import com.facebook.react.ReactInstanceManager; -import com.facebook.react.ReactRootView; -import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler; -import com.facebook.react.shell.MainReactPackage; -import com.facebook.soloader.SoLoader; - -import com.tradle.react.*; // <--- import - -public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler { - - private ReactInstanceManager mReactInstanceManager; - private ReactRootView mReactRootView; +public class MainActivity extends ReactActivity { + /** + * Returns the name of the main component registered from JavaScript. + * This is used to schedule rendering of the component. + */ @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mReactRootView = new ReactRootView(this); - - mReactInstanceManager = ReactInstanceManager.builder() - .setApplication(getApplication()) - .setBundleAssetName("index.bundle") - .setJSMainModuleName("index") - .addPackage(new MainReactPackage()) - .addPackage(new UdpSocketsModule()) // <- add here - .setUseDeveloperSupport(BuildConfig.DEBUG) - .setInitialLifecycleState(LifecycleState.RESUMED) - .build(); - - mReactRootView.startReactApplication(mReactInstanceManager, "rctsockets", null); - - setContentView(mReactRootView); - } - - @Override - public boolean onKeyUp(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) { - mReactInstanceManager.showDevOptionsDialog(); - return true; - } - return super.onKeyUp(keyCode, event); - } - - @Override - public void onBackPressed() { - if (mReactInstanceManager != null) { - mReactInstanceManager.onBackPressed(); - } else { - super.onBackPressed(); - } - } - - @Override - public void invokeDefaultOnBackPressed() { - super.onBackPressed(); - } - - @Override - protected void onPause() { - super.onPause(); - - if (mReactInstanceManager != null) { - mReactInstanceManager.onPause(); - } - } - - @Override - protected void onResume() { - super.onResume(); - - if (mReactInstanceManager != null) { - mReactInstanceManager.onResume(this); - } + protected String getMainComponentName() { + return "rctsockets"; } } diff --git a/examples/rctsockets/android/app/src/main/java/com/rctsockets/MainApplication.java b/examples/rctsockets/android/app/src/main/java/com/rctsockets/MainApplication.java new file mode 100644 index 0000000..0c0c88b --- /dev/null +++ b/examples/rctsockets/android/app/src/main/java/com/rctsockets/MainApplication.java @@ -0,0 +1,37 @@ +package com.rctsockets; + +import android.app.Application; +import android.util.Log; + +import com.facebook.react.ReactApplication; +import com.facebook.react.ReactInstanceManager; +import com.facebook.react.ReactNativeHost; +import com.facebook.react.ReactPackage; +import com.facebook.react.shell.MainReactPackage; +import com.tradle.react.UdpSocketsModule; + +import java.util.Arrays; +import java.util.List; + +public class MainApplication extends Application implements ReactApplication { + + private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { + @Override + protected boolean getUseDeveloperSupport() { + return BuildConfig.DEBUG; + } + + @Override + protected List getPackages() { + return Arrays.asList( + new MainReactPackage(), + new UdpSocketsModule() + ); + } + }; + + @Override + public ReactNativeHost getReactNativeHost() { + return mReactNativeHost; + } +} diff --git a/examples/rctsockets/android/app/src/main/res/values/strings.xml b/examples/rctsockets/android/app/src/main/res/values/strings.xml index 8409235..1dd488e 100644 --- a/examples/rctsockets/android/app/src/main/res/values/strings.xml +++ b/examples/rctsockets/android/app/src/main/res/values/strings.xml @@ -1,3 +1,5 @@ + + rctsockets diff --git a/examples/rctsockets/android/build.gradle b/examples/rctsockets/android/build.gradle index ccdfc4e..fcba4c5 100644 --- a/examples/rctsockets/android/build.gradle +++ b/examples/rctsockets/android/build.gradle @@ -16,5 +16,9 @@ allprojects { repositories { mavenLocal() jcenter() + maven { + // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm + url "$rootDir/../node_modules/react-native/android" + } } } diff --git a/examples/rctsockets/android/keystores/BUCK b/examples/rctsockets/android/keystores/BUCK new file mode 100644 index 0000000..15da20e --- /dev/null +++ b/examples/rctsockets/android/keystores/BUCK @@ -0,0 +1,8 @@ +keystore( + name = 'debug', + store = 'debug.keystore', + properties = 'debug.keystore.properties', + visibility = [ + 'PUBLIC', + ], +) diff --git a/examples/rctsockets/android/keystores/debug.keystore.properties b/examples/rctsockets/android/keystores/debug.keystore.properties new file mode 100644 index 0000000..121bfb4 --- /dev/null +++ b/examples/rctsockets/android/keystores/debug.keystore.properties @@ -0,0 +1,4 @@ +key.store=debug.keystore +key.alias=androiddebugkey +key.store.password=android +key.alias.password=android diff --git a/examples/rctsockets/android/settings.gradle b/examples/rctsockets/android/settings.gradle index 716006f..4e006c5 100644 --- a/examples/rctsockets/android/settings.gradle +++ b/examples/rctsockets/android/settings.gradle @@ -2,4 +2,4 @@ rootProject.name = 'rctsockets' include ':app' include ':react-native-udp' -project(':react-native-udp').projectDir = new File(settingsDir, '../node_modules/react-native-udp/android') +project(':react-native-udp').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-udp/android') diff --git a/examples/rctsockets/index.android.js b/examples/rctsockets/index.android.js new file mode 100644 index 0000000..466b959 --- /dev/null +++ b/examples/rctsockets/index.android.js @@ -0,0 +1,127 @@ +/** + * Sample React Native App + * https://github.com/facebook/react-native + * @flow + */ + +import React, { Component } from 'react'; +import { + AppRegistry, + ScrollView, + StyleSheet, + Text, + View +} from 'react-native'; + +import base64 from 'base64-js'; +import dgram from 'dgram'; + +function randomPort() { + return Math.random() * 60536 | 0 + 5000 // 60536-65536 +} + +// only works for 8-bit chars +function toByteArray(obj) { + var uint = new Uint8Array(obj.length); + for (var i = 0, l = obj.length; i < l; i++){ + uint[i] = obj.charCodeAt(i); + } + + return new Uint8Array(uint); +} + +class rctsockets extends Component { + constructor(props) { + super(props); + + this.updateChatter = this.updateChatter.bind(this); + this.state = { chatter: [] }; + } + + updateChatter(msg) { + this.setState({ + chatter: this.state.chatter.concat([msg]) + }); + } + + componentDidMount() { + let self = this; + + let a = dgram.createSocket('udp4'); + let aPort = randomPort(); + a.bind(aPort, function(err) { + if (err) throw err; + self.updateChatter('a bound to ' + JSON.stringify(a.address())); + }) + + let b = dgram.createSocket('udp4'); + var bPort = randomPort(); + b.bind(bPort, function(err) { + if (err) throw err; + self.updateChatter('b bound to ' + JSON.stringify(b.address())); + }) + + a.on('message', function(data, rinfo) { + var str = String.fromCharCode.apply(null, new Uint8Array(data)); + self.updateChatter('a received echo ' + str + ' ' + JSON.stringify(rinfo)); + a.close(); + b.close(); + }) + + b.on('message', function(data, rinfo) { + var str = String.fromCharCode.apply(null, new Uint8Array(data)); + self.updateChatter('b received ' + str + ' ' + JSON.stringify(rinfo)); + + // echo back + b.send(data, 0, data.length, aPort, '127.0.0.1', function(err) { + if (err) throw err + self.updateChatter('b echoed data') + }) + }) + + b.once('listening', function() { + var msg = toByteArray('hello') + a.send(msg, 0, msg.length, bPort, '127.0.0.1', function(err) { + if (err) throw err + self.updateChatter('a sent data') + }) + }) + } + + render() { + return ( + + + {this.state.chatter.map((msg, index) => { + return ( + + {msg} + + ); + })} + + + ); + } +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + backgroundColor: '#F5FCFF', + }, + welcome: { + fontSize: 20, + textAlign: 'center', + margin: 10, + }, + instructions: { + textAlign: 'center', + color: '#333333', + marginBottom: 5, + }, +}); + +AppRegistry.registerComponent('rctsockets', () => rctsockets); diff --git a/examples/rctsockets/index.ios.js b/examples/rctsockets/index.ios.js new file mode 100644 index 0000000..466b959 --- /dev/null +++ b/examples/rctsockets/index.ios.js @@ -0,0 +1,127 @@ +/** + * Sample React Native App + * https://github.com/facebook/react-native + * @flow + */ + +import React, { Component } from 'react'; +import { + AppRegistry, + ScrollView, + StyleSheet, + Text, + View +} from 'react-native'; + +import base64 from 'base64-js'; +import dgram from 'dgram'; + +function randomPort() { + return Math.random() * 60536 | 0 + 5000 // 60536-65536 +} + +// only works for 8-bit chars +function toByteArray(obj) { + var uint = new Uint8Array(obj.length); + for (var i = 0, l = obj.length; i < l; i++){ + uint[i] = obj.charCodeAt(i); + } + + return new Uint8Array(uint); +} + +class rctsockets extends Component { + constructor(props) { + super(props); + + this.updateChatter = this.updateChatter.bind(this); + this.state = { chatter: [] }; + } + + updateChatter(msg) { + this.setState({ + chatter: this.state.chatter.concat([msg]) + }); + } + + componentDidMount() { + let self = this; + + let a = dgram.createSocket('udp4'); + let aPort = randomPort(); + a.bind(aPort, function(err) { + if (err) throw err; + self.updateChatter('a bound to ' + JSON.stringify(a.address())); + }) + + let b = dgram.createSocket('udp4'); + var bPort = randomPort(); + b.bind(bPort, function(err) { + if (err) throw err; + self.updateChatter('b bound to ' + JSON.stringify(b.address())); + }) + + a.on('message', function(data, rinfo) { + var str = String.fromCharCode.apply(null, new Uint8Array(data)); + self.updateChatter('a received echo ' + str + ' ' + JSON.stringify(rinfo)); + a.close(); + b.close(); + }) + + b.on('message', function(data, rinfo) { + var str = String.fromCharCode.apply(null, new Uint8Array(data)); + self.updateChatter('b received ' + str + ' ' + JSON.stringify(rinfo)); + + // echo back + b.send(data, 0, data.length, aPort, '127.0.0.1', function(err) { + if (err) throw err + self.updateChatter('b echoed data') + }) + }) + + b.once('listening', function() { + var msg = toByteArray('hello') + a.send(msg, 0, msg.length, bPort, '127.0.0.1', function(err) { + if (err) throw err + self.updateChatter('a sent data') + }) + }) + } + + render() { + return ( + + + {this.state.chatter.map((msg, index) => { + return ( + + {msg} + + ); + })} + + + ); + } +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + backgroundColor: '#F5FCFF', + }, + welcome: { + fontSize: 20, + textAlign: 'center', + margin: 10, + }, + instructions: { + textAlign: 'center', + color: '#333333', + marginBottom: 5, + }, +}); + +AppRegistry.registerComponent('rctsockets', () => rctsockets); diff --git a/examples/rctsockets/index.js b/examples/rctsockets/index.js deleted file mode 100644 index a3c7502..0000000 --- a/examples/rctsockets/index.js +++ /dev/null @@ -1,106 +0,0 @@ -'use strict'; - -var React = require('react-native'); -var { - AppRegistry, - StyleSheet, - Text, - View, -} = React; - -// require('./test/simple/test-dgram-address') -// require('./test/simple/test-dgram-bind-default-address') -// require('./test/simple/test-dgram-bind-shared-ports') - -function randomPort() { - return Math.random() * 60536 | 0 + 5000 // 60536-65536 -} - -var base64 = require('base64-js') -var dgram = require('dgram') -var a = dgram.createSocket('udp4') -var aPort = randomPort() -a.bind(aPort, function(err) { - if (err) throw err - - console.log('address', a.address()) -}) - -var b = dgram.createSocket('udp4') -var bPort = randomPort() -b.bind(bPort, function(err) { - if (err) throw err - - console.log('address', b.address()) -}) - -a.on('message', function(data, rinfo) { - var str = String.fromCharCode.apply(null, new Uint8Array(data)); - console.log('a received', str, rinfo) - a.close() - b.close() -}) - -b.on('message', function(data, rinfo) { - var str = String.fromCharCode.apply(null, new Uint8Array(data)); - console.log('b received', str, rinfo) - - // echo back - b.send(data, 0, data.length, aPort, '127.0.0.1', function(err) { - if (err) throw err - - console.log('sent') - }) -}) - -b.once('listening', function() { - var msg = toByteArray('hello') - a.send(msg, 0, msg.length, bPort, '127.0.0.1', function(err) { - if (err) throw err - - console.log('sent') - }) -}) - -var rctsockets = React.createClass({ - render: function() { - return ( - - - Open Dev Tools to see socket chatter - - - ); - } -}); - -var styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', - backgroundColor: '#F5FCFF', - }, - welcome: { - fontSize: 20, - textAlign: 'center', - margin: 10, - }, - instructions: { - textAlign: 'center', - color: '#333333', - marginBottom: 5, - }, -}); - -// only works for 8-bit chars -function toByteArray(obj) { - var uint = new Uint8Array(obj.length); - for (var i = 0, l = obj.length; i < l; i++){ - uint[i] = obj.charCodeAt(i); - } - - return new Uint8Array(uint); -} - -AppRegistry.registerComponent('rctsockets', () => rctsockets); diff --git a/examples/rctsockets/ios/rctsockets.xcodeproj/project.pbxproj b/examples/rctsockets/ios/rctsockets.xcodeproj/project.pbxproj index ad58bb9..7037626 100644 --- a/examples/rctsockets/ios/rctsockets.xcodeproj/project.pbxproj +++ b/examples/rctsockets/ios/rctsockets.xcodeproj/project.pbxproj @@ -5,7 +5,6 @@ }; objectVersion = 46; objects = { - /* Begin PBXBuildFile section */ 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; }; 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; }; @@ -20,9 +19,10 @@ 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; + 140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; - 96682ACC1BFE5269001E549C /* libUdpSockets.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 96682ACB1BFE525D001E549C /* libUdpSockets.a */; }; + 51E8FB48A4754FC3AB6D5C55 /* libUdpSockets.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A5F1397EE5564F7BB7A34B37 /* libUdpSockets.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -103,27 +103,20 @@ remoteGlobalIDString = 58B5119B1A9E6C1200147676; remoteInfo = RCTText; }; - 96682ACA1BFE525D001E549C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 96682ABC1BFE525C001E549C /* UdpSockets.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = UdpSockets; - }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; }; - 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = ""; }; - 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = "../node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj"; sourceTree = ""; }; - 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = ""; }; - 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = ""; }; - 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = ""; }; + 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = main.jsbundle; path = main.jsbundle; sourceTree = ""; }; + 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = ../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj; sourceTree = ""; }; + 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = ../node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj; sourceTree = ""; }; + 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj; sourceTree = ""; }; + 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = ../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj; sourceTree = ""; }; + 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = ../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj; sourceTree = ""; }; 00E356EE1AD99517003FC87E /* rctsocketsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = rctsocketsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 00E356F21AD99517003FC87E /* rctsocketsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = rctsocketsTests.m; sourceTree = ""; }; - 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = ""; }; - 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = ""; }; + 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = ../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj; sourceTree = ""; }; + 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = ../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = ""; }; 13B07F961A680F5B00A75B9A /* rctsockets.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = rctsockets.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = rctsockets/AppDelegate.h; sourceTree = ""; }; 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = rctsockets/AppDelegate.m; sourceTree = ""; }; @@ -131,10 +124,11 @@ 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = rctsockets/Images.xcassets; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = rctsockets/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = rctsockets/main.m; sourceTree = ""; }; - 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = ""; }; - 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; }; - 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; }; - 96682ABC1BFE525C001E549C /* UdpSockets.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = UdpSockets.xcodeproj; path = "../node_modules/react-native-udp/ios/UdpSockets.xcodeproj"; sourceTree = ""; }; + 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = ../node_modules/react-native/React/React.xcodeproj; sourceTree = ""; }; + 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = ../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj; sourceTree = ""; }; + 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../node_modules/react-native/Libraries/Text/RCTText.xcodeproj; sourceTree = ""; }; + DA9E7BD5F68E4015A48EEEA5 /* UdpSockets.xcodeproj */ = {isa = PBXFileReference; name = "UdpSockets.xcodeproj"; path = "../node_modules/react-native-udp/ios/UdpSockets.xcodeproj"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; }; + A5F1397EE5564F7BB7A34B37 /* libUdpSockets.a */ = {isa = PBXFileReference; name = "libUdpSockets.a"; path = "libUdpSockets.a"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -142,6 +136,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -149,7 +144,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 96682ACC1BFE5269001E549C /* libUdpSockets.a in Frameworks */, 146834051AC3E58100842450 /* libReact.a in Frameworks */, 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */, @@ -160,6 +154,7 @@ 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */, 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */, 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */, + 51E8FB48A4754FC3AB6D5C55 /* libUdpSockets.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -272,7 +267,6 @@ 832341AE1AAA6A7D00B99B32 /* Libraries */ = { isa = PBXGroup; children = ( - 96682ABC1BFE525C001E549C /* UdpSockets.xcodeproj */, 146833FF1AC3E56700842450 /* React.xcodeproj */, 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */, @@ -283,6 +277,7 @@ 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */, 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */, 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */, + DA9E7BD5F68E4015A48EEEA5 /* UdpSockets.xcodeproj */, ); name = Libraries; sourceTree = ""; @@ -316,14 +311,6 @@ name = Products; sourceTree = ""; }; - 96682ABD1BFE525C001E549C /* Products */ = { - isa = PBXGroup; - children = ( - 96682ACB1BFE525D001E549C /* libUdpSockets.a */, - ); - name = Products; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -369,7 +356,7 @@ 83CBB9F71A601CBA00E9B192 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0610; + LastUpgradeCheck = 610; ORGANIZATIONNAME = Facebook; TargetAttributes = { 00E356ED1AD99517003FC87E = { @@ -430,10 +417,6 @@ ProductGroup = 146834001AC3E56700842450 /* Products */; ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */; }, - { - ProductGroup = 96682ABD1BFE525C001E549C /* Products */; - ProjectRef = 96682ABC1BFE525C001E549C /* UdpSockets.xcodeproj */; - }, ); projectRoot = ""; targets = ( @@ -514,13 +497,6 @@ remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 96682ACB1BFE525D001E549C /* libUdpSockets.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libUdpSockets.a; - remoteRef = 96682ACA1BFE525D001E549C /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; /* End PBXReferenceProxy section */ /* Begin PBXResourcesBuildPhase section */ @@ -555,7 +531,8 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "./react-native-xcode.sh"; + shellScript = "export NODE_BINARY=node\n../node_modules/react-native/packager/react-native-xcode.sh"; + showEnvVarsInLog = 1; }; /* End PBXShellScriptBuildPhase section */ @@ -604,10 +581,6 @@ isa = XCBuildConfiguration; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - ); GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", @@ -617,6 +590,10 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/rctsockets.app/rctsockets"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + ); }; name = Debug; }; @@ -625,15 +602,15 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - ); INFOPLIST_FILE = rctsocketsTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/rctsockets.app/rctsockets"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + ); }; name = Release; }; @@ -646,10 +623,15 @@ "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, "$(SRCROOT)/../node_modules/react-native/React/**", + "$(SRCROOT)/../node_modules/react-native-udp/ios/**", ); - INFOPLIST_FILE = rctsockets/Info.plist; + INFOPLIST_FILE = "rctsockets/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - OTHER_LDFLAGS = "-ObjC"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + "-lc++", + ); PRODUCT_NAME = rctsockets; }; name = Debug; @@ -662,10 +644,15 @@ "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, "$(SRCROOT)/../node_modules/react-native/React/**", + "$(SRCROOT)/../node_modules/react-native-udp/ios/**", ); - INFOPLIST_FILE = rctsockets/Info.plist; + INFOPLIST_FILE = "rctsockets/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - OTHER_LDFLAGS = "-ObjC"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + "-lc++", + ); PRODUCT_NAME = rctsockets; }; name = Release; @@ -708,6 +695,7 @@ "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, "$(SRCROOT)/../node_modules/react-native/React/**", + "$(SRCROOT)/../node_modules/react-native-udp/ios/**", ); IPHONEOS_DEPLOYMENT_TARGET = 7.0; MTL_ENABLE_DEBUG_INFO = YES; @@ -748,6 +736,7 @@ "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, "$(SRCROOT)/../node_modules/react-native/React/**", + "$(SRCROOT)/../node_modules/react-native-udp/ios/**", ); IPHONEOS_DEPLOYMENT_TARGET = 7.0; MTL_ENABLE_DEBUG_INFO = NO; diff --git a/examples/rctsockets/ios/rctsockets/AppDelegate.m b/examples/rctsockets/ios/rctsockets/AppDelegate.m index c33f836..6c61219 100644 --- a/examples/rctsockets/ios/rctsockets/AppDelegate.m +++ b/examples/rctsockets/ios/rctsockets/AppDelegate.m @@ -9,6 +9,7 @@ #import "AppDelegate.h" +#import "RCTBundleURLProvider.h" #import "RCTRootView.h" @implementation AppDelegate @@ -17,37 +18,17 @@ { NSURL *jsCodeLocation; - /** - * Loading JavaScript code - uncomment the one you want. - * - * OPTION 1 - * Load from development server. Start the server from the repository root: - * - * $ npm start - * - * To run on device, change `localhost` to the IP address of your computer - * (you can get this by typing `ifconfig` into the terminal and selecting the - * `inet` value under `en0:`) and make sure your computer and iOS device are - * on the same Wi-Fi network. - */ - - jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.bundle?platform=ios&dev=true"]; - - /** - * OPTION 2 - * Load from pre-bundled file on disk. The static bundle is automatically - * generated by "Bundle React Native code and images" build step. - */ - -// jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; + [[RCTBundleURLProvider sharedSettings] setDefaults]; + jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil]; RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"rctsockets" initialProperties:nil launchOptions:launchOptions]; + rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; - UIViewController *rootViewController = [[UIViewController alloc] init]; + UIViewController *rootViewController = [UIViewController new]; rootViewController.view = rootView; self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible]; diff --git a/examples/rctsockets/ios/rctsockets/Info.plist b/examples/rctsockets/ios/rctsockets/Info.plist index cddf076..e98ebb0 100644 --- a/examples/rctsockets/ios/rctsockets/Info.plist +++ b/examples/rctsockets/ios/rctsockets/Info.plist @@ -38,11 +38,17 @@ NSLocationWhenInUseUsageDescription - NSAppTransportSecurity - - - NSAllowsArbitraryLoads - - + NSAppTransportSecurity + + + NSExceptionDomains + + localhost + + NSTemporaryExceptionAllowsInsecureHTTPLoads + + + + diff --git a/examples/rctsockets/ios/rctsocketsTests/rctsocketsTests.m b/examples/rctsockets/ios/rctsocketsTests/rctsocketsTests.m index 0436bcc..abb8da9 100644 --- a/examples/rctsockets/ios/rctsocketsTests/rctsocketsTests.m +++ b/examples/rctsockets/ios/rctsocketsTests/rctsocketsTests.m @@ -13,7 +13,7 @@ #import "RCTLog.h" #import "RCTRootView.h" -#define TIMEOUT_SECONDS 240 +#define TIMEOUT_SECONDS 600 #define TEXT_TO_LOOK_FOR @"Welcome to React Native!" @interface rctsocketsTests : XCTestCase @@ -42,7 +42,7 @@ BOOL foundElement = NO; __block NSString *redboxError = nil; - RCTSetLogFunction(^(RCTLogLevel level, NSString *fileName, NSNumber *lineNumber, NSString *message) { + RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { if (level >= RCTLogLevelError) { redboxError = message; } diff --git a/examples/rctsockets/ios/react-native-xcode.sh b/examples/rctsockets/ios/react-native-xcode.sh deleted file mode 100755 index c5a8abc..0000000 --- a/examples/rctsockets/ios/react-native-xcode.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash -# Copyright (c) 2015-present, Facebook, Inc. -# All rights reserved. -# -# This source code is licensed under the BSD-style license found in the -# LICENSE file in the root directory of this source tree. An additional grant -# of patent rights can be found in the PATENTS file in the same directory. - -# Bundle React Native app's code and image assets. -# This script is supposed to be invoked as part of Xcode build process -# and relies on envoronment variables (including PWD) set by Xcode - -case "$CONFIGURATION" in - Debug) - DEV=true - ;; - Release) - DEV=false - ;; - "") - echo "$0 must be invoked by Xcode" - exit 1 - ;; - *) - echo "Unsupported value of \$CONFIGURATION=$CONFIGURATION" - exit 1 - ;; -esac - -# Xcode project file for React Native apps is located in ios/ subfolder -cd .. - -set -x -DEST=$CONFIGURATION_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH - -# Define NVM_DIR and source the nvm.sh setup script -[ -z "$NVM_DIR" ] && export NVM_DIR="$HOME/.nvm" - -if [[ -s "$HOME/.nvm/nvm.sh" ]]; then - . "$HOME/.nvm/nvm.sh" -elif [[ -x "$(command -v brew)" && -s "$(brew --prefix nvm)/nvm.sh" ]]; then - . "$(brew --prefix nvm)/nvm.sh" -fi - -react-native bundle \ - --entry-file index.js \ - --platform ios \ - --dev $DEV \ - --bundle-output "$DEST/main.jsbundle" \ - --assets-dest "$DEST" diff --git a/examples/rctsockets/package.json b/examples/rctsockets/package.json index 19f5725..eefb6bb 100644 --- a/examples/rctsockets/package.json +++ b/examples/rctsockets/package.json @@ -3,13 +3,15 @@ "version": "0.0.1", "private": true, "scripts": { - "start": "react-native start" + "start": "node node_modules/react-native/local-cli/cli.js start" }, "browser": { "dgram": "react-native-udp" }, "dependencies": { - "react-native": "^0.14.2", + "base64-js": "^1.1.2", + "react": "15.2.1", + "react-native": "0.29.2", "react-native-udp": "../../" } } diff --git a/ios/ReactUdp.podspec b/ios/ReactUdp.podspec deleted file mode 100644 index 9c3a0de..0000000 --- a/ios/ReactUdp.podspec +++ /dev/null @@ -1,24 +0,0 @@ -Pod::Spec.new do |s| - s.name = 'ReactUdp' - s.version = '1.1.1' - s.summary = 'node\'s dgram API in React Native.' - s.description = <<-DESC - Enables accessing udp sockets in React Native. - DESC - s.homepage = 'https://github.com/tradle/react-native-udp' - s.license = { :type => 'MIT' } - s.authors = { 'Mark Vayngrib' => 'mark.vayngrib@lablz.com' } - s.source = { :git => 'https://github.com/tradle/react-native-udp.git' } - s.default_subspec = 'Core' - s.requires_arc = true - s.platform = :ios, '7.0' - s.prepare_command = 'npm install --production' - s.preserve_paths = 'node_modules', '**/*.js', 'package.json' - s.header_mappings_dir = '.' - s.dependency 'React' - - s.subspec 'Core' do |ss| - ss.source_files = '*.{c,h,m}', 'CocoaAsyncSocket/*.{h,m}' - ss.preserve_paths = '*.js' - end -end