├── .watchmanconfig ├── .gitattributes ├── .babelrc ├── android ├── settings.gradle ├── app │ ├── src │ │ └── main │ │ │ ├── res │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ └── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── java │ │ │ └── com │ │ │ │ └── technology_stack │ │ │ │ ├── MainActivity.java │ │ │ │ └── MainApplication.java │ │ │ └── AndroidManifest.xml │ ├── BUCK │ ├── proguard-rules.pro │ └── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── keystores │ ├── debug.keystore.properties │ └── BUCK ├── build.gradle ├── gradle.properties ├── gradlew.bat └── gradlew ├── app.json ├── .vscode └── settings.json ├── src ├── reducers │ ├── LibraryReducer.js │ ├── SelectionReducer.js │ ├── index.js │ └── LibraryList.json ├── actions │ └── index.js ├── components │ ├── common │ │ ├── index.js │ │ ├── Spinner.js │ │ ├── CardSection.js │ │ ├── Card.js │ │ ├── Header.js │ │ ├── Button.js │ │ └── Input.js │ ├── LibraryList.js │ └── ListItem.js └── app.js ├── .buckconfig ├── index.android.js ├── index.ios.js ├── jsconfig.json ├── __tests__ ├── index.ios.js └── index.android.js ├── ios ├── technology_stack │ ├── AppDelegate.h │ ├── main.m │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── AppDelegate.m │ ├── Info.plist │ └── Base.lproj │ │ └── LaunchScreen.xib ├── technology_stackTests │ ├── Info.plist │ └── technology_stackTests.m ├── technology_stack-tvOSTests │ └── Info.plist ├── technology_stack-tvOS │ └── Info.plist └── technology_stack.xcodeproj │ ├── xcshareddata │ └── xcschemes │ │ ├── technology_stack.xcscheme │ │ └── technology_stack-tvOS.xcscheme │ └── project.pbxproj ├── package.json ├── .gitignore ├── .flowconfig └── README.md /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["react-native"] 3 | } 4 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'technology_stack' 2 | 3 | include ':app' 4 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "technology_stack", 3 | "displayName": "technology_stack" 4 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | } -------------------------------------------------------------------------------- /src/reducers/LibraryReducer.js: -------------------------------------------------------------------------------- 1 | import data from './LibraryList.json'; 2 | 3 | export default () => data; 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | technology_stack 3 | 4 | -------------------------------------------------------------------------------- /.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanbumi/react-native-redux-technology_stack/HEAD/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/keystores/debug.keystore.properties: -------------------------------------------------------------------------------- 1 | key.store=debug.keystore 2 | key.alias=androiddebugkey 3 | key.store.password=android 4 | key.alias.password=android 5 | -------------------------------------------------------------------------------- /index.android.js: -------------------------------------------------------------------------------- 1 | import { AppRegistry } from 'react-native'; 2 | import App from './src/app'; 3 | 4 | AppRegistry.registerComponent('technology_stack', () => App); 5 | -------------------------------------------------------------------------------- /index.ios.js: -------------------------------------------------------------------------------- 1 | import { AppRegistry } from 'react-native'; 2 | import App from './src/app'; 3 | 4 | AppRegistry.registerComponent('technology_stack', () => App); 5 | -------------------------------------------------------------------------------- /src/actions/index.js: -------------------------------------------------------------------------------- 1 | export const selectLibrary = (libraryId) => { 2 | return { 3 | type: 'select_library', 4 | payload: libraryId 5 | }; 6 | }; -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanbumi/react-native-redux-technology_stack/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanbumi/react-native-redux-technology_stack/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanbumi/react-native-redux-technology_stack/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanbumi/react-native-redux-technology_stack/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": true, 4 | "allowSyntheticDefaultImports": true 5 | }, 6 | "exclude": [ 7 | "node_modules" 8 | ] 9 | } -------------------------------------------------------------------------------- /android/keystores/BUCK: -------------------------------------------------------------------------------- 1 | keystore( 2 | name = "debug", 3 | properties = "debug.keystore.properties", 4 | store = "debug.keystore", 5 | visibility = [ 6 | "PUBLIC", 7 | ], 8 | ) 9 | -------------------------------------------------------------------------------- /src/components/common/index.js: -------------------------------------------------------------------------------- 1 | export * from './Button'; 2 | export * from './Card'; 3 | export * from './CardSection'; 4 | export * from './Header'; 5 | export * from './Input'; 6 | export * from './Spinner'; 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip 6 | -------------------------------------------------------------------------------- /src/reducers/SelectionReducer.js: -------------------------------------------------------------------------------- 1 | export default (state = null, action) => { 2 | // console.log(action); 3 | // return null; 4 | switch (action.type) { 5 | case 'select_library': 6 | return action.payload; 7 | default: 8 | return state; 9 | } 10 | }; 11 | 12 | -------------------------------------------------------------------------------- /src/reducers/index.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux'; 2 | import LibraryReducer from './LibraryReducer'; 3 | import SelectionReducer from './SelectionReducer'; 4 | 5 | export default combineReducers({ 6 | // libraries: () => [] 7 | libraries: LibraryReducer, 8 | selectedLibraryId: SelectionReducer 9 | }); -------------------------------------------------------------------------------- /__tests__/index.ios.js: -------------------------------------------------------------------------------- 1 | import 'react-native'; 2 | import React from 'react'; 3 | import Index from '../index.ios.js'; 4 | 5 | // Note: test renderer must be required after react-native. 6 | import renderer from 'react-test-renderer'; 7 | 8 | it('renders correctly', () => { 9 | const tree = renderer.create( 10 | 11 | ); 12 | }); 13 | -------------------------------------------------------------------------------- /__tests__/index.android.js: -------------------------------------------------------------------------------- 1 | import 'react-native'; 2 | import React from 'react'; 3 | import Index from '../index.android.js'; 4 | 5 | // Note: test renderer must be required after react-native. 6 | import renderer from 'react-test-renderer'; 7 | 8 | it('renders correctly', () => { 9 | const tree = renderer.create( 10 | 11 | ); 12 | }); 13 | -------------------------------------------------------------------------------- /src/components/common/Spinner.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, ActivityIndicator } from 'react-native'; 3 | 4 | const Spinner = ({ size }) => { 5 | return ( 6 | 7 | 8 | 9 | ); 10 | }; 11 | 12 | const styles = { 13 | spinnerStyle: { 14 | flex: 1, 15 | justifyContent: 'center', 16 | alignItems: 'center' 17 | } 18 | }; 19 | 20 | export { Spinner }; 21 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/technology_stack/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.technology_stack; 2 | 3 | import com.facebook.react.ReactActivity; 4 | 5 | public class MainActivity extends ReactActivity { 6 | 7 | /** 8 | * Returns the name of the main component registered from JavaScript. 9 | * This is used to schedule rendering of the component. 10 | */ 11 | @Override 12 | protected String getMainComponentName() { 13 | return "technology_stack"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ios/technology_stack/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (nonatomic, strong) UIWindow *window; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /src/components/common/CardSection.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View } from 'react-native'; 3 | 4 | const CardSection = (props) => { 5 | return ( 6 | 7 | {props.children} 8 | 9 | ); 10 | }; 11 | 12 | const styles = { 13 | containerStyle: { 14 | borderBottomWidth: 1, 15 | padding: 5, 16 | backgroundColor: '#fff', 17 | justifyContent: 'flex-start', 18 | flexDirection: 'row', 19 | borderColor: '#ddd', 20 | position: 'relative' 21 | } 22 | }; 23 | 24 | export { CardSection }; 25 | -------------------------------------------------------------------------------- /ios/technology_stack/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | #import "AppDelegate.h" 13 | 14 | int main(int argc, char * argv[]) { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "technology_stack", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "start": "node node_modules/react-native/local-cli/cli.js start", 7 | "test": "jest" 8 | }, 9 | "dependencies": { 10 | "react": "16.0.0-alpha.6", 11 | "react-native": "0.44.2", 12 | "react-redux": "^5.0.5", 13 | "redux": "^3.6.0" 14 | }, 15 | "devDependencies": { 16 | "babel-jest": "20.0.3", 17 | "babel-preset-react-native": "1.9.2", 18 | "jest": "20.0.4", 19 | "react-test-renderer": "16.0.0-alpha.6" 20 | }, 21 | "jest": { 22 | "preset": "react-native" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/app.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View } from 'react-native'; 3 | import { Provider } from 'react-redux'; 4 | import { createStore } from 'redux'; 5 | import reducers from './reducers'; 6 | import { Header } from './components/common'; 7 | import LibraryList from './components/LibraryList'; 8 | 9 | const App = () => { 10 | return( 11 | 12 | 13 |
14 | 15 | 16 | 17 | ) 18 | }; 19 | 20 | export default App; -------------------------------------------------------------------------------- /src/components/common/Card.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View } from 'react-native'; 3 | 4 | const Card = (props) => { 5 | return ( 6 | 7 | {props.children} 8 | 9 | ); 10 | }; 11 | 12 | const styles = { 13 | containerStyle: { 14 | borderWidth: 1, 15 | borderRadius: 2, 16 | borderColor: '#ddd', 17 | borderBottomWidth: 0, 18 | shadowColor: '#000', 19 | shadowOffset: { width: 0, height: 2 }, 20 | shadowOpacity: 0.1, 21 | shadowRadius: 2, 22 | elevation: 1, 23 | marginLeft: 5, 24 | marginRight: 5, 25 | marginTop: 10 26 | } 27 | }; 28 | 29 | export { Card }; 30 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:2.2.3' 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | mavenLocal() 18 | jcenter() 19 | maven { 20 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 21 | url "$rootDir/../node_modules/react-native/android" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ios/technology_stack/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /ios/technology_stackTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /ios/technology_stack-tvOSTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/components/common/Header.js: -------------------------------------------------------------------------------- 1 | // Import libraries for making a component 2 | import React from 'react'; 3 | import { Text, View } from 'react-native'; 4 | 5 | // Make a component 6 | const Header = (props) => { 7 | const { textStyle, viewStyle } = styles; 8 | 9 | return ( 10 | 11 | {props.headerText} 12 | 13 | ); 14 | }; 15 | 16 | const styles = { 17 | viewStyle: { 18 | backgroundColor: '#F8F8F8', 19 | justifyContent: 'center', 20 | alignItems: 'center', 21 | height: 60, 22 | paddingTop: 15, 23 | shadowColor: '#000', 24 | shadowOffset: { width: 0, height: 2 }, 25 | shadowOpacity: 0.2, 26 | elevation: 2, 27 | position: 'relative' 28 | }, 29 | textStyle: { 30 | fontSize: 20 31 | } 32 | }; 33 | 34 | // Make the component available to other parts of the app 35 | export { Header }; 36 | -------------------------------------------------------------------------------- /src/components/common/Button.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Text, TouchableOpacity } from 'react-native'; 3 | 4 | const Button = ({ onPress, children }) => { 5 | const { buttonStyle, textStyle } = styles; 6 | 7 | return ( 8 | 9 | 10 | {children} 11 | 12 | 13 | ); 14 | }; 15 | 16 | const styles = { 17 | textStyle: { 18 | alignSelf: 'center', 19 | color: '#007aff', 20 | fontSize: 16, 21 | fontWeight: '600', 22 | paddingTop: 10, 23 | paddingBottom: 10 24 | }, 25 | buttonStyle: { 26 | flex: 1, 27 | alignSelf: 'stretch', 28 | backgroundColor: '#fff', 29 | borderRadius: 5, 30 | borderWidth: 1, 31 | borderColor: '#007aff', 32 | marginLeft: 5, 33 | marginRight: 5 34 | } 35 | }; 36 | 37 | export { Button }; 38 | -------------------------------------------------------------------------------- /src/components/LibraryList.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { ListView } from 'react-native'; 3 | import { connect } from 'react-redux'; 4 | import ListItem from './ListItem'; 5 | 6 | class LibraryList extends Component { 7 | componentWillMount() { 8 | const ds = new ListView.DataSource({ 9 | rowHasChanged: (r1, r2) => r1 !== r2 10 | }); 11 | 12 | this.dataSource = ds.cloneWithRows(this.props.libraries); 13 | } 14 | 15 | renderRow(library) { 16 | return ; 17 | } 18 | 19 | render(){ 20 | return ( 21 | 25 | ); 26 | } 27 | } 28 | 29 | const mapStateToProps = state => { 30 | return { libraries: state.libraries }; 31 | }; 32 | 33 | export default connect(mapStateToProps)(LibraryList); -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | android.useDeprecatedNdk=true 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | 33 | # node.js 34 | # 35 | node_modules/ 36 | npm-debug.log 37 | yarn-error.log 38 | 39 | # BUCK 40 | buck-out/ 41 | \.buckd/ 42 | *.keystore 43 | 44 | # fastlane 45 | # 46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 47 | # screenshots whenever they are needed. 48 | # For more information about the recommended setup visit: 49 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 50 | 51 | fastlane/report.xml 52 | fastlane/Preview.html 53 | fastlane/screenshots 54 | -------------------------------------------------------------------------------- /src/components/common/Input.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { TextInput, View, Text } from 'react-native'; 3 | 4 | const Input = ({ label, value, onChangeText, placeholder, secureTextEntry }) => { 5 | const { inputStyle, labelStyle, containerStyle } = styles; 6 | 7 | return ( 8 | 9 | {label} 10 | 18 | 19 | ); 20 | }; 21 | 22 | const styles = { 23 | inputStyle: { 24 | color: '#000', 25 | paddingRight: 5, 26 | paddingLeft: 5, 27 | fontSize: 18, 28 | lineHeight: 23, 29 | flex: 2 30 | }, 31 | labelStyle: { 32 | fontSize: 18, 33 | paddingLeft: 20, 34 | flex: 1 35 | }, 36 | containerStyle: { 37 | height: 40, 38 | flex: 1, 39 | flexDirection: 'row', 40 | alignItems: 'center' 41 | } 42 | }; 43 | 44 | export { Input }; 45 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/technology_stack/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.technology_stack; 2 | 3 | import android.app.Application; 4 | 5 | import com.facebook.react.ReactApplication; 6 | import com.facebook.react.ReactNativeHost; 7 | import com.facebook.react.ReactPackage; 8 | import com.facebook.react.shell.MainReactPackage; 9 | import com.facebook.soloader.SoLoader; 10 | 11 | import java.util.Arrays; 12 | import java.util.List; 13 | 14 | public class MainApplication extends Application implements ReactApplication { 15 | 16 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { 17 | @Override 18 | public boolean getUseDeveloperSupport() { 19 | return BuildConfig.DEBUG; 20 | } 21 | 22 | @Override 23 | protected List getPackages() { 24 | return Arrays.asList( 25 | new MainReactPackage() 26 | ); 27 | } 28 | }; 29 | 30 | @Override 31 | public ReactNativeHost getReactNativeHost() { 32 | return mReactNativeHost; 33 | } 34 | 35 | @Override 36 | public void onCreate() { 37 | super.onCreate(); 38 | SoLoader.init(this, /* native exopackage */ false); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 19 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /ios/technology_stack/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import "AppDelegate.h" 11 | 12 | #import 13 | #import 14 | 15 | @implementation AppDelegate 16 | 17 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 18 | { 19 | NSURL *jsCodeLocation; 20 | 21 | jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil]; 22 | 23 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 24 | moduleName:@"technology_stack" 25 | initialProperties:nil 26 | launchOptions:launchOptions]; 27 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 28 | 29 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 30 | UIViewController *rootViewController = [UIViewController new]; 31 | rootViewController.view = rootView; 32 | self.window.rootViewController = rootViewController; 33 | [self.window makeKeyAndVisible]; 34 | return YES; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /src/components/ListItem.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Text, 3 | TouchableWithoutFeedback, 4 | View, 5 | LayoutAnimation 6 | } from 'react-native'; 7 | import { connect } from 'react-redux'; 8 | import { CardSection } from './common'; 9 | import * as actions from '../actions'; 10 | 11 | class ListItem extends Component { 12 | componentWillUpdate() { 13 | LayoutAnimation.spring(); 14 | } 15 | 16 | renderDescription() { 17 | const { library, expanded } = this.props; 18 | 19 | if (expanded) { 20 | return ( 21 | 22 | 23 | {library.description} 24 | 25 | 26 | ); 27 | } 28 | }; 29 | 30 | render() { 31 | const {titleStyle} = styles; 32 | const {id, title} = this.props.library; 33 | 34 | return( 35 | this.props.selectLibrary(id)} 37 | > 38 | 39 | 40 | 41 | {title} 42 | 43 | 44 | {this.renderDescription()} 45 | 46 | 47 | ); 48 | } 49 | } 50 | 51 | const styles = { 52 | titleStyle: { 53 | fontSize: 18, 54 | paddingLeft: 15, 55 | fontWeight: '600', 56 | color: '#000' 57 | } 58 | } 59 | 60 | const mapStateToProps = (state, ownProps) => { 61 | const expanded = state.selectedLibraryId === ownProps.library.id; 62 | 63 | return { expanded } 64 | }; 65 | 66 | export default connect(mapStateToProps, actions)(ListItem); 67 | 68 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore unexpected extra "@providesModule" 9 | .*/node_modules/.*/node_modules/fbjs/.* 10 | 11 | ; Ignore duplicate module providers 12 | ; For RN Apps installed via npm, "Libraries" folder is inside 13 | ; "node_modules/react-native" but in the source repo it is in the root 14 | .*/Libraries/react-native/React.js 15 | .*/Libraries/react-native/ReactNative.js 16 | 17 | [include] 18 | 19 | [libs] 20 | node_modules/react-native/Libraries/react-native/react-native-interface.js 21 | node_modules/react-native/flow 22 | flow/ 23 | 24 | [options] 25 | emoji=true 26 | 27 | module.system=haste 28 | 29 | experimental.strict_type_args=true 30 | 31 | munge_underscores=true 32 | 33 | 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' 34 | 35 | suppress_type=$FlowIssue 36 | suppress_type=$FlowFixMe 37 | suppress_type=$FixMe 38 | 39 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(4[0-2]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) 40 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(4[0-2]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ 41 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy 42 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError 43 | 44 | unsafe.enable_getters_and_setters=true 45 | 46 | [version] 47 | ^0.42.0 48 | -------------------------------------------------------------------------------- /ios/technology_stack-tvOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UIViewControllerBasedStatusBarAppearance 38 | 39 | NSLocationWhenInUseUsageDescription 40 | 41 | NSAppTransportSecurity 42 | 43 | 44 | NSExceptionDomains 45 | 46 | localhost 47 | 48 | NSExceptionAllowsInsecureHTTPLoads 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /android/app/BUCK: -------------------------------------------------------------------------------- 1 | # To learn about Buck see [Docs](https://buckbuild.com/). 2 | # To run your application with Buck: 3 | # - install Buck 4 | # - `npm start` - to start the packager 5 | # - `cd android` 6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` 7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 8 | # - `buck install -r android/app` - compile, install and run application 9 | # 10 | 11 | lib_deps = [] 12 | 13 | for jarfile in glob(['libs/*.jar']): 14 | name = 'jars__' + jarfile[jarfile.rindex('/') + 1: jarfile.rindex('.jar')] 15 | lib_deps.append(':' + name) 16 | prebuilt_jar( 17 | name = name, 18 | binary_jar = jarfile, 19 | ) 20 | 21 | for aarfile in glob(['libs/*.aar']): 22 | name = 'aars__' + aarfile[aarfile.rindex('/') + 1: aarfile.rindex('.aar')] 23 | lib_deps.append(':' + name) 24 | android_prebuilt_aar( 25 | name = name, 26 | aar = aarfile, 27 | ) 28 | 29 | android_library( 30 | name = "all-libs", 31 | exported_deps = lib_deps, 32 | ) 33 | 34 | android_library( 35 | name = "app-code", 36 | srcs = glob([ 37 | "src/main/java/**/*.java", 38 | ]), 39 | deps = [ 40 | ":all-libs", 41 | ":build_config", 42 | ":res", 43 | ], 44 | ) 45 | 46 | android_build_config( 47 | name = "build_config", 48 | package = "com.technology_stack", 49 | ) 50 | 51 | android_resource( 52 | name = "res", 53 | package = "com.technology_stack", 54 | res = "src/main/res", 55 | ) 56 | 57 | android_binary( 58 | name = "app", 59 | keystore = "//android/keystores:debug", 60 | manifest = "src/main/AndroidManifest.xml", 61 | package_type = "debug", 62 | deps = [ 63 | ":app-code", 64 | ], 65 | ) 66 | -------------------------------------------------------------------------------- /ios/technology_stack/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | technology_stack 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UIViewControllerBasedStatusBarAppearance 40 | 41 | NSLocationWhenInUseUsageDescription 42 | 43 | NSAppTransportSecurity 44 | 45 | 46 | NSExceptionDomains 47 | 48 | localhost 49 | 50 | NSExceptionAllowsInsecureHTTPLoads 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /ios/technology_stackTests/technology_stackTests.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | #import 12 | 13 | #import 14 | #import 15 | 16 | #define TIMEOUT_SECONDS 600 17 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!" 18 | 19 | @interface technology_stackTests : XCTestCase 20 | 21 | @end 22 | 23 | @implementation technology_stackTests 24 | 25 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test 26 | { 27 | if (test(view)) { 28 | return YES; 29 | } 30 | for (UIView *subview in [view subviews]) { 31 | if ([self findSubviewInView:subview matching:test]) { 32 | return YES; 33 | } 34 | } 35 | return NO; 36 | } 37 | 38 | - (void)testRendersWelcomeScreen 39 | { 40 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; 41 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 42 | BOOL foundElement = NO; 43 | 44 | __block NSString *redboxError = nil; 45 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 46 | if (level >= RCTLogLevelError) { 47 | redboxError = message; 48 | } 49 | }); 50 | 51 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 52 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 53 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 54 | 55 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { 56 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 57 | return YES; 58 | } 59 | return NO; 60 | }]; 61 | } 62 | 63 | RCTSetLogFunction(RCTDefaultLogFunction); 64 | 65 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 66 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 67 | } 68 | 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /src/reducers/LibraryList.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 0, 4 | "title": "Webpack", 5 | "description": "Webpack is a module bundler. It packs CommonJs/AMD modules i. e. for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand." 6 | }, 7 | { 8 | "id": 1, 9 | "title": "React", 10 | "description": "React makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes." 11 | }, 12 | { 13 | "id": 2, 14 | "title": "Redux", 15 | "description": "Redux is a predictable state container for JavaScript apps. It helps you write applications that behave consistently, run in different environments (client, server, and native), and are easy to test." 16 | }, 17 | { 18 | "id": 3, 19 | "title": "React-Redux", 20 | "description": "React-Redux is the official set of bindings between the React and Redux libraries. With this library you can keep your views and data in sync." 21 | }, 22 | { 23 | "id": 4, 24 | "title": "Lodash", 25 | "description": "A modern JavaScript utility library delivering modularity, performance, & extras. Lodash is released under the MIT license & supports modern environments." 26 | }, 27 | { 28 | "id": 5, 29 | "title": "Redux-Thunk", 30 | "description": "Redux Thunk middleware allows you to write action creators that return a function instead of an action. The thunk can be used to delay the dispatch of an action, or to dispatch only if a certain condition is met." 31 | }, 32 | { 33 | "id": 6, 34 | "title": "ESLint", 35 | "description": "ESLint is an open source JavaScript linting utility originally created by Nicholas C. Zakas in June 2013. Code linting is a type of static analysis that is frequently used to find problematic patterns or code that doesn’t adhere to certain style guidelines." 36 | }, 37 | { 38 | "id": 7, 39 | "title": "Babel", 40 | "description": "Babel has support for the latest version of JavaScript through syntax transformers. These plugins allow you to use new syntax, right now without waiting for browser support." 41 | }, 42 | { 43 | "id": 8, 44 | "title": "Axios", 45 | "description": "Promise based HTTP client for the browser and node.js. With Axios, you can make XMLHttpRequests from the browser or Node with the full Promise Api." 46 | } 47 | ] -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Disabling obfuscation is useful if you collect stack traces from production crashes 20 | # (unless you are using a system that supports de-obfuscate the stack traces). 21 | -dontobfuscate 22 | 23 | # React Native 24 | 25 | # Keep our interfaces so they can be used by other ProGuard rules. 26 | # See http://sourceforge.net/p/proguard/bugs/466/ 27 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip 28 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters 29 | -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip 30 | 31 | # Do not strip any method/class that is annotated with @DoNotStrip 32 | -keep @com.facebook.proguard.annotations.DoNotStrip class * 33 | -keep @com.facebook.common.internal.DoNotStrip class * 34 | -keepclassmembers class * { 35 | @com.facebook.proguard.annotations.DoNotStrip *; 36 | @com.facebook.common.internal.DoNotStrip *; 37 | } 38 | 39 | -keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * { 40 | void set*(***); 41 | *** get*(); 42 | } 43 | 44 | -keep class * extends com.facebook.react.bridge.JavaScriptModule { *; } 45 | -keep class * extends com.facebook.react.bridge.NativeModule { *; } 46 | -keepclassmembers,includedescriptorclasses class * { native ; } 47 | -keepclassmembers class * { @com.facebook.react.uimanager.UIProp ; } 48 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp ; } 49 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup ; } 50 | 51 | -dontwarn com.facebook.react.** 52 | 53 | # TextLayoutBuilder uses a non-public Android constructor within StaticLayout. 54 | # See libs/proxy/src/main/java/com/facebook/fbui/textlayoutbuilder/proxy for details. 55 | -dontwarn android.text.StaticLayout 56 | 57 | # okhttp 58 | 59 | -keepattributes Signature 60 | -keepattributes *Annotation* 61 | -keep class okhttp3.** { *; } 62 | -keep interface okhttp3.** { *; } 63 | -dontwarn okhttp3.** 64 | 65 | # okio 66 | 67 | -keep class sun.misc.Unsafe { *; } 68 | -dontwarn java.nio.file.* 69 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 70 | -dontwarn okio.** 71 | -------------------------------------------------------------------------------- /ios/technology_stack/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /ios/technology_stack.xcodeproj/xcshareddata/xcschemes/technology_stack.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /ios/technology_stack.xcodeproj/xcshareddata/xcschemes/technology_stack-tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | 3 | import com.android.build.OutputFile 4 | 5 | /** 6 | * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets 7 | * and bundleReleaseJsAndAssets). 8 | * These basically call `react-native bundle` with the correct arguments during the Android build 9 | * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the 10 | * bundle directly from the development server. Below you can see all the possible configurations 11 | * and their defaults. If you decide to add a configuration block, make sure to add it before the 12 | * `apply from: "../../node_modules/react-native/react.gradle"` line. 13 | * 14 | * project.ext.react = [ 15 | * // the name of the generated asset file containing your JS bundle 16 | * bundleAssetName: "index.android.bundle", 17 | * 18 | * // the entry file for bundle generation 19 | * entryFile: "index.android.js", 20 | * 21 | * // whether to bundle JS and assets in debug mode 22 | * bundleInDebug: false, 23 | * 24 | * // whether to bundle JS and assets in release mode 25 | * bundleInRelease: true, 26 | * 27 | * // whether to bundle JS and assets in another build variant (if configured). 28 | * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants 29 | * // The configuration property can be in the following formats 30 | * // 'bundleIn${productFlavor}${buildType}' 31 | * // 'bundleIn${buildType}' 32 | * // bundleInFreeDebug: true, 33 | * // bundleInPaidRelease: true, 34 | * // bundleInBeta: true, 35 | * 36 | * // the root of your project, i.e. where "package.json" lives 37 | * root: "../../", 38 | * 39 | * // where to put the JS bundle asset in debug mode 40 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", 41 | * 42 | * // where to put the JS bundle asset in release mode 43 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release", 44 | * 45 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 46 | * // require('./image.png')), in debug mode 47 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", 48 | * 49 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 50 | * // require('./image.png')), in release mode 51 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", 52 | * 53 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means 54 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to 55 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle 56 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ 57 | * // for example, you might want to remove it from here. 58 | * inputExcludes: ["android/**", "ios/**"], 59 | * 60 | * // override which node gets called and with what additional arguments 61 | * nodeExecutableAndArgs: ["node"], 62 | * 63 | * // supply additional arguments to the packager 64 | * extraPackagerArgs: [] 65 | * ] 66 | */ 67 | 68 | apply from: "../../node_modules/react-native/react.gradle" 69 | 70 | /** 71 | * Set this to true to create two separate APKs instead of one: 72 | * - An APK that only works on ARM devices 73 | * - An APK that only works on x86 devices 74 | * The advantage is the size of the APK is reduced by about 4MB. 75 | * Upload all the APKs to the Play Store and people will download 76 | * the correct one based on the CPU architecture of their device. 77 | */ 78 | def enableSeparateBuildPerCPUArchitecture = false 79 | 80 | /** 81 | * Run Proguard to shrink the Java bytecode in release builds. 82 | */ 83 | def enableProguardInReleaseBuilds = false 84 | 85 | android { 86 | compileSdkVersion 23 87 | buildToolsVersion "23.0.1" 88 | 89 | defaultConfig { 90 | applicationId "com.technology_stack" 91 | minSdkVersion 16 92 | targetSdkVersion 22 93 | versionCode 1 94 | versionName "1.0" 95 | ndk { 96 | abiFilters "armeabi-v7a", "x86" 97 | } 98 | } 99 | splits { 100 | abi { 101 | reset() 102 | enable enableSeparateBuildPerCPUArchitecture 103 | universalApk false // If true, also generate a universal APK 104 | include "armeabi-v7a", "x86" 105 | } 106 | } 107 | buildTypes { 108 | release { 109 | minifyEnabled enableProguardInReleaseBuilds 110 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 111 | } 112 | } 113 | // applicationVariants are e.g. debug, release 114 | applicationVariants.all { variant -> 115 | variant.outputs.each { output -> 116 | // For each separate APK per architecture, set a unique version code as described here: 117 | // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits 118 | def versionCodes = ["armeabi-v7a":1, "x86":2] 119 | def abi = output.getFilter(OutputFile.ABI) 120 | if (abi != null) { // null for the universal-debug, universal-release variants 121 | output.versionCodeOverride = 122 | versionCodes.get(abi) * 1048576 + defaultConfig.versionCode 123 | } 124 | } 125 | } 126 | } 127 | 128 | dependencies { 129 | compile fileTree(dir: "libs", include: ["*.jar"]) 130 | compile "com.android.support:appcompat-v7:23.0.1" 131 | compile "com.facebook.react:react-native:+" // From node_modules 132 | } 133 | 134 | // Run this once to be able to run the application with BUCK 135 | // puts all compile dependencies into folder libs for BUCK to use 136 | task copyDownloadableDepsToLibs(type: Copy) { 137 | from configurations.compile 138 | into 'libs' 139 | } 140 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tutorial Redux Bahasa Indonesia 2 | 3 | ## Apa itu Redux? 4 | 5 | [Redux](http://redux.js.org/) adalah predictable state container untuk JavaScript aplikasi. 6 | 7 | Redux membantu anda untuk membuat aplikasi dengan efisien dan menjaga konsistensi pada environment yang berbeda, seperti pada client, server, dan native, serta mudah untuk melakukan testing. Selain daripada itu, Redux memberikan pengalaman yang luar biasa kepada para pengembang, seperti live code editing dan time traveling debugger. 8 | 9 | Anda dapat menggunakan Redux untuk aplikasi React, atau dengan view library yang lain, dengan ukuran size yang cukup kecil berkisar 2kB, termasuk dependencies. 10 | 11 | ![diagram-redux](http://res.cloudinary.com/medioxtra/image/upload/v1495836771/Redux_ripkwn.png) 12 | 13 | **Detail Diagram** 14 | 15 | **Reducer** adalah function yang memiliki kembalian data (return some data). 16 | 17 | **Action** adalah plain **JavaScript Object** ( "{ }" ) yang memberitahukan Reducer cara memodifikasi data. Syarat dari Action adalah harus memiliki sebuah **type** property. 18 | 19 | **State** adalah Data dari sebuah aplikasi yang digunakan, misalnya: value dari input field, data list, gambar, seluruh data yang berada di dalam aplikasi, dikumpulkan menjadi **State**. 20 | 21 | **Store** adalah container yang menyimpan Reducer & State pada sebuah aplikasi. 22 | 23 | > **Untuk Diingat** Jadi Redux merukan satu kesatuan yang terdiri dari **Store** & **Action**, dimana Store terdiri dari **Reducer** & **State**. 24 | 25 | ### Cara membuat Redux 26 | 27 | // Step membuat Redux 28 | 29 | // 1-Membuat function reducer 30 | const reducer = () => []; 31 | 32 | // 2-Membuat store 33 | const store = Redux.createStore(reducer); 34 | 35 | // 3-Menampilkan current state 36 | store.getState(); 37 | 38 | **Detail code** 39 | 40 | 1. Membuat function reducer: 41 | 42 | const reducer = () => []; 43 | 44 | 2. Create Store: 45 | 46 | const store = Redux.createStore(); 47 | 48 | 3. Lewatkan reducer ke dalam store argument: 49 | 50 | const store = Redux.createStore(reducer); 51 | 52 | 4. Menampilkan store pada state saat ini (current state): 53 | 54 | store.getState(); 55 | 56 | ![create-redux](http://res.cloudinary.com/medioxtra/image/upload/v1495839324/redux_efae12.png) 57 | Ralat *empty array 58 | 59 | ### Contoh aplikasi kecil Redux 60 | 61 | Sebuah string 'asdf' (kata/word) akan dirubah (split) menjadi menjadi array dari single karakter (huruf) : 62 | 63 | ![contoh-redux](http://res.cloudinary.com/medioxtra/image/upload/v1495859052/Redux-contoh-case_jqxexi.png) 64 | 65 | **Actions** 66 | Memuat string: 'asdf' & instruksi: split, kemudian di lewatkan/oper/teruskan ke Reducer. 67 | 68 | **Reducer** 69 | Akan me-return/mengembalikan string yang sudah di split kedalam sebuah array, kemdian di teruskan ke State. 70 | 71 | **State** 72 | Akan menerima dari Reducer data single karakter array ['a', 's', 'd', 'f']. 73 | 74 | **Update Code diatas** 75 | 76 | ![tiny-app-redux](http://res.cloudinary.com/medioxtra/image/upload/v1495861579/Redux_sample_tiny_app_dkpooy.png) 77 | 78 | **Membuat aplikasi redux 'asdf'** 79 | 80 | // 1-Membuat Action 81 | const action = { 82 | type: 'split_string', 83 | payload: 'asdf' 84 | }; 85 | 86 | // 2-Mengupdate function reducer 87 | const reducer = (state=[], action) => { 88 | if (action.type === 'split_string') { 89 | return action.payload.split(''); 90 | } 91 | 92 | return state; 93 | }; 94 | 95 | // 3-Membuat store 96 | const store = Redux.createStore(reducer); 97 | 98 | // 4-Meneruskan action ke reducer 99 | store.dispatch(action); 100 | 101 | // 5-Menampilkan current state 102 | store.getState(); 103 | 104 | **Detail Code** 105 | 106 | 1. Membuat action -> plain **JS Object**, action memiliki 2 property -> **type** (instruksi) & **payload** (data yang akan dimodifikasi). 107 | 108 | const action = { 109 | type: 'split_string', 110 | payload: 'asdf' 111 | }; 112 | 113 | 2. Mengupdate reducer untuk menghandle action, reducer memiliki 2 argument: **current state** & **action**. 114 | 115 | const reducer = (state = [], action) => { 116 | if (action.type === 'split_string'){ 117 | return action.payload.split(''); 118 | } 119 | return state; 120 | }; 121 | 122 | 3. Meneruskan perintah Action ke Reducer dengan perintah: **dispatch(action)**; 123 | 124 | store.dispatch(action); 125 | 126 | 4. Menampilkan hasil update state 127 | 128 | store.getState(); 129 | 130 | 5. Hasilnya kolom sebelah kanan: 131 | 132 | {"type":"split_string","payload":"asdf"} 133 | ["a","s","d","f"] 134 | 135 | **Menambah action baru** 136 | 137 | ![action2](http://res.cloudinary.com/medioxtra/image/upload/v1495866691/Menambah_action_baru_af8iax.png) 138 | 139 | **Update Reducer lagi** 140 | 141 | ![Update reducer lagi](http://res.cloudinary.com/medioxtra/image/upload/v1495866847/Update_reducer_lagi_v5edi5.png) 142 | 143 | **Detail Code** 144 | 145 | Baris 25, Untuk menambah action baru: 146 | 147 | const action2 = { 148 | type: 'add_character', 149 | payload: 'a' 150 | } 151 | 152 | Baris 31, Meneruskan action ke reducer: 153 | 154 | store.dispatch(action2); 155 | 156 | Baris 33, Menampilkan state yg sudah terupdate: 157 | 158 | store.getState(); 159 | 160 | Baris 4, Menambahkan else if : 161 | 162 | } else if (action.type === 'add_character'){ 163 | 164 | Baris 5 - 6, Melakukan return dengan mutable state: 165 | 166 | //state.push(action.payload); 167 | //return state; 168 | 169 | Baris 7, Melakukan return dengan menambahkan state baru: 170 | 171 | return [...state, action.payload]; 172 | 173 | Hasilnya: 174 | 175 | {"type":"add_character","payload":"a"} 176 | ["a","s","d","f","a"] 177 | 178 | ## Membuat aplikasi Redux dengan React Native 179 | 180 | ![finish](http://res.cloudinary.com/medioxtra/image/upload/c_scale,h_600,w_300/v1496580861/finish_mfqxwy.png) 181 | 182 | Kita akan membuat aplikasi yang menampilkan daftar keahlian dalam programming dimana bila item daftar keahlian tersebut di klik makan akan tampil keterangan dari item tersebut dibawahnya. 183 | 184 | **Membuat new aplikasi** 185 | 186 | react-native init technology_stack 187 | 188 | **Menginstall library Redux & React Redux** 189 | 190 | Buka cli dengan Administrator, ketik: 191 | 192 | npm install --save redux react-redux 193 | 194 | ![instal redux](http://res.cloudinary.com/medioxtra/image/upload/v1495921096/instal_redux_react-redux_utr0hk.png) 195 | 196 | **Menyiapkan Android Emulator, dengan Android Studio atau lainnya** 197 | 198 | Open new folder > technology_stack 199 | 200 | **Dari terminal cmd, jalankan Emulator Android** 201 | 202 | react-native run-android 203 | 204 | ![and-emulator](http://res.cloudinary.com/medioxtra/image/upload/c_scale,h_453,w_200/v1495870704/and-emulator_czcw9f.png) 205 | 206 | **Membuka aplikasi dengan code editor tambahkan folder baru src** 207 | 208 | /src 209 | 210 | **Tambahkan file app.js** 211 | 212 | /src/app.js 213 | 214 | Tambahkan component pada app.js sbb: 215 | 216 | import React from 'react'; 217 | import { View } from 'react-native'; 218 | 219 | const App = () => { 220 | return( 221 | 222 | ); 223 | }; 224 | 225 | export default App; 226 | 227 | **Hapus semua file pada:** 228 | 229 | index.android.js & index.ios.js 230 | 231 | **Dan ketik code minimum untuk ke dua file tsb:** 232 | 233 | import { AppRegistry } from 'react-native'; 234 | import App from './src/app' 235 | 236 | AppRegistry.registerComponent('technology_stack', () => App); 237 | 238 | **Update file app.js dengan menambahkan Redux Provider & createStore** 239 | 240 | import React from 'react'; 241 | import { View } from 'react-native'; 242 | import { Provider } from 'react-redux'; 243 | import { createStore } from 'redux'; 244 | 245 | const App = () => { 246 | return( 247 | 248 | 249 | 250 | ) 251 | }; 252 | 253 | export default App; 254 | 255 | **Detail Code**: 256 | 257 | - import **Provider** dari react-native. 258 | - import **createStore** dari redux. 259 | - Bungkus **View Tag** dengan **Provider Tag** dan teruskan **createStore** pada store property. 260 | 261 | ![diagram-provider](http://res.cloudinary.com/medioxtra/image/upload/v1495922876/diagram-provider_orqm1a.png) 262 | 263 | **Detail gambar**: 264 | 265 | - Provider Tag bekerja sama dengan Store. 266 | - Masing-masing memiliki tugas spesifik. 267 | - Store menyimpan State aplikasi atau semua data didalam aplikasi. 268 | - Provider menterjemahkan semua data yang ada di Store sehingga dapat digunakan pada React Aplikasi. 269 | - Provider sebagai **Perekat Komunikasi** dengan React. 270 | 271 | ### Menambahkan reducers 272 | 273 | 1. Didalam folder src tambkan folder baru **reducers** dan file index.js didalam nya, serta ketikkan code sbb: 274 | 275 | import { combineReducer } from 'redux'; 276 | 277 | export default combineReducer({ 278 | libraries: () => [] 279 | }); 280 | 281 | **Penjelasan code**: 282 | 283 | - Import **combineReducer** dari **Redux**, menggunakan combine karena akan lebih dari satu **reducer** yang akan di import nantinya. 284 | - Export default combineReducer, yang melewatkan **libraries function** yang mengembalikan array kosong. 285 | 286 | 2. Udate file app.js dengan menambahkan code sbb: 287 | 288 | import reducers from './reducers'; 289 | 290 | const App = () => { 291 | return( 292 | 293 | 294 | 295 | ) 296 | }; 297 | 298 | export default App; 299 | 300 | **Penjelasan code**: 301 | 302 | - import **reducer** dari **folder reducers** tadi. 303 | - teruskan reducers di **store property**, *dimana setiap create **Store** harus melewatkan 1 buah **function reducers***. 304 | 305 | ### Membuat header & render header. 306 | 307 | 1. Buat folder baru components > common : 308 | 309 | Kemudian buat component2x sebagai berikut: 310 | Button.js, Card.js, CardSection.js, Header.js, index.js, Input.js, Spinner.js 311 | 312 | -> file ini adalah component reusable, silahkan download dari file repo ini. 313 | 314 | 2. Import Header di app.js 315 | 316 | import { Header } from './components/common' 317 | 318 | 3. Update code di app.js: 319 | 320 | 321 | 322 |
323 | 324 | 325 | 326 | 4. Refresh emulator screen. 327 | 328 | ![tech_stack](http://res.cloudinary.com/medioxtra/image/upload/c_scale,h_300,w_150/v1495948874/technology_stack_vnas6e.png) 329 | 330 | ### Membuat State Library 331 | 332 | Kita akan membuat **State**, dalam aplikasi ini akan ada 2 buah library data, yaitu **List of Library** dan **Library Currently Selected**, List Library adalah daftar seluruh data dan Library Selected adalah data yang di select/view oleh user. 333 | 334 | Aplikasi ini tidak melibatkan database di server, sebaliknya *hard coding* (statik data) didalam app itu sendiri (daftar data akan di masukan ke dalam aplikasi secara manual). 335 | 336 | ### Reducer 337 | 338 | **Reducer** menghasilkan **State** data dan State adalah **Data** dari sebuah aplikasi. 339 | 340 | 1. Didalam folder reducers **index.js** akan memuat library data di dalamnya: 341 | 342 | libraries = () => [] 343 | 344 | 2. Selanjutnya kita akan membuat 2 buah **reducer** terpisah, yaitu **Library Reducer** dan **Selection Reducer**. 345 | 346 | ![two-reducers](http://res.cloudinary.com/medioxtra/image/upload/c_scale,h_200,w_700/v1495953135/dua-reducer_yjstan.png) 347 | 348 | Untuk itu buatlah file baru nama **LibraryReducer.js** dalam folder reducers, dan tuliskan codenya sbb: 349 | 350 | export default () => [ 351 | 352 | ]; 353 | 354 | 3. Kemudian import ke dalam file **index.js**, pada file reducers/index.js: 355 | 356 | import LibraryReducer from './LibraryReducer'; 357 | 358 | 4. Update function combineReducer pada file reducers/index.js sbb: 359 | 360 | export default combineReducers({ 361 | libraries: LibraryReducer 362 | }); 363 | 364 | **Detail code** -> Perlu di ingat disini kita lakukan assign **LibraryReducer** dengan **KEY** **libraries**. 365 | 366 | 5. Membuat file json **LibraryList.json** di dalam folder reducers. (Silahkan copas file json di repository). 367 | 368 | > **Catatan** file json memuat content seluruh nya adalah string, jadi seluruh text content selain value integer harus diberi *"double/single quote"*, contoh: 369 | 370 | "id": 0, 371 | "title": "Webpack" 372 | .... 373 | 374 | 6. Pada file LibraryReducer.js import file json tsb sebagai **data** dari array of object: 375 | 376 | import data from './reducers/LibraryList.json' 377 | 378 | export default () => [ 379 | 380 | ]; 381 | 382 | Update menjadi: 383 | 384 | export default () => data; 385 | 386 | 7. Membuat component baru untuk merender list of data json diatas. Buatlah file components/LibraryList.js dan masukan code boiler plate sbb: 387 | 388 | import React, { Component } from 'react'; 389 | 390 | class LibraryList extends Component { 391 | render(){ 392 | return; 393 | } 394 | } 395 | 396 | export default LibraryList; 397 | 398 | Untuk menampilkannya kita membutuhkan **connect helper**. 399 | 400 | ### Connect Function. 401 | 402 | ![connect-helper](http://res.cloudinary.com/medioxtra/image/upload/c_scale,h_416,w_400/v1496299423/connect-helper_kywazf.png) 403 | 404 | **Detil gambar**: 405 | 406 | Untuk menghubungkan antara Store dan LibraryList kita membutuhkan **Connect helper**, Connect helper adalah function yang akan mendorong (push) data dari Store menuju ke LibraryList. 407 | 408 | Connect helper adalah fitur dari React-Redux library. Dimana React-Redux adalah perekat antara programming Redux dengan React. 409 | 410 | Cara penerapannya sbb: 411 | 412 | 1. import connect pada file LibraryList.js 413 | 414 | import { connect } from 'react-redux'; 415 | 416 | 2. aplikasi connect pada export: 417 | 418 | export default connect()(LibraryList); 419 | 420 | 3. Buat function baru mapStateToProps(): 421 | 422 | const mapStateToProps = state => { 423 | console.log(state); 424 | }; 425 | 426 | Detail code: 427 | 428 | Tujuan dari function mapStateToProps adalah mengambil Global State Object dari Store dan di maping di jadikan sebagai props dari LibraryList. 429 | 430 | Test pada console: 431 | 432 | console.log(state); 433 | 434 | Refresh screen: 435 | 436 | ![console-log](http://res.cloudinary.com/medioxtra/image/upload/c_scale,h_325,w_400/v1496323525/console-log_rpzwyx.png) 437 | 438 | Keterangan gambar: 439 | 440 | Terlihat pada console data dengan key libraries array tampil. 441 | 442 | Sekarang bagaimana cara nya mapStateToProps function ini bisa ditampilkan kedalam component LibraryList, caranya adalah -> object yang di return dalam function mapStateToProps dapat digunakan sebagai props pada component class. 443 | 444 | Step nya: 445 | 446 | * Return dalam object, ganti console log dengan return object LibraryList. 447 | 448 | return { libraries: state.libraries } 449 | 450 | Menjadi: 451 | 452 | const mapStateToProps = state => { 453 | return { libraries: state.libraries }; 454 | }; 455 | 456 | * Update component LibraList menjadi sbb: 457 | 458 | class LibraryList extends Component { 459 | render(){ 460 | console.log(this.props); 461 | return; 462 | } 463 | } 464 | 465 | *gunakan console.log untuk test do console. 466 | 467 | ![console-log-2](http://res.cloudinary.com/medioxtra/image/upload/c_scale,h_170,w_400/v1496327623/console-log-2_gwy2dy.png) 468 | 469 | **Diagram cara kerja App dengan Redux** 470 | 471 | ![cara-kerja](http://res.cloudinary.com/medioxtra/image/upload/c_scale,h_477,w_500/v1496328035/how_it_work_diagram_tuh14v.png) 472 | 473 | Keterangan gambar: 474 | 475 | Pada saat aplikasi boot up untuk pertama kali, Redux membuat Store baru menggunakan Library Reducer, 476 | instance Store tersebut menjalankan Reducer satu kali, sehingga akan menghasilkan State yang kita sebut libraries, yang adalah array yang berisi object data. 477 | Setelah terbentuk Store, akan di lewatkan ke Provider sebagai **props**, Provider adalah merupakan React Component, penghubung antara React & Redux. 478 | Kemudian App merender ke screen yang notabene adalah render dari LibraryList component. 479 | Connect function mengubungkan LibraryList dengan Provider, dengan function **mapStateToProps** menjadikan Data State menjadi Props, sehingga bisa ditampilkan oleh App sebagai props dari LibraryList, kemudian LibraryList akan ditampilkan di app.js untuk tampil di screen. 480 | 481 | --- 482 | 483 | ### React Native ListView. 484 | 485 | **ListView** adalah component disediakan oleh **React Native** untuk menangani render data yang sangat besar, tanpa membebani kerja memory handphone. Cara kerja ListView adalah membuat **instant** component hanya untuk data yang tampil di screen saja, bila user scroll screen kebawah atau keatas maka ListView akan melakukan **Reusable Component** untuk data berikutnya yang akan tampil saat user scroll. 486 | 487 | ![list-view](http://res.cloudinary.com/medioxtra/image/upload/c_scale,h_450,w_150/v1496381436/listView_wobr5g.png) 488 | 489 | ### Menerapkan ListView pada Aplikasi. 490 | 491 | 1. Pada file LibraryList.js import ListView from ReactNative. 492 | 493 | import ListView from 'react-native'; 494 | 495 | 2. Menambahkan componentWillMount lifecycle method, agar pada saat aplikasi start dapat tertriger. 496 | 497 | class LibraryList extends Component { 498 | componentWillMount() { 499 | 500 | } 501 | 502 | render(){ 503 | ... 504 | } 505 | 506 | 3. Tambahkan code boilerplate (copas) pada method diatas hingga menjadi sbb: 507 | 508 | componentWillMount() { 509 | const ds = new ListView.DataSource({ 510 | rowHasChanged: (r1, r2) => r1 !== r2 511 | }); 512 | 513 | this.dataSource = ds.cloneWithRows(this.props.libraries); 514 | } 515 | 516 | 4. Update render method diatas dengan menambahkan ListView Tag: 517 | 518 | render(){ 519 | return( 520 | 523 | ) 524 | } 525 | 526 | 5. Tambahkan render row pada props ListView: 527 | 528 | render(){ 529 | return( 530 | 534 | 535 | 6. Define helper method renderRow untuk merender single item of data dalam bentuk row, tempatkan diatas render() method: 536 | 537 | renderRow() { 538 | 539 | } 540 | 541 | 7. Membuat component baru dengan nama **ListItem** untuk memanggil data dalam bentuk single row. 542 | 543 | import React, { Component } from 'react'; 544 | 545 | class ListItem extends Component { 546 | render() { 547 | 548 | } 549 | } 550 | 551 | export default ListItem; 552 | 553 | 7. Pada file LibraryList import ListItem: 554 | 555 | 8. Tambahkan ListItem Tag pada renderRow method dan tambahkan library sebagai **argument** dan jadikan props pada ListItem: 556 | 557 | renderRow(library) { 558 | ; 559 | } 560 | 561 | 9. Pada ListItem.js tambahkan CardSection Tag untuk menampilkan List dari Item data. 562 | 563 | import CardSection from './common'; 564 | 565 | 10. Refresh screen -> sukses! 566 | 567 | ![sukses-screen](http://res.cloudinary.com/medioxtra/image/upload/c_scale,h_550,w_300/v1496402975/success-screen_tj0m9i.png) 568 | 569 | ### Tambahkan Style 570 | 571 | const styles = { 572 | titleStyle: { 573 | fontSize: 18, 574 | paddingLeft: 15 575 | } 576 | } 577 | 578 | Lakukan destructure: 579 | 580 | const {titleStyle} = styles; 581 | 582 | Sisipkan: 583 | 584 | 585 | 586 | Pada app.js, beri style pada view: 587 | 588 | 589 | 590 | ### Membuat selection reducer 591 | 592 | Buat file baru beri nama reducers/SelectionReducer.js: 593 | 594 | export default () => { 595 | return null; 596 | }; 597 | 598 | **return null** pada reducer untuk mencegah error undefined. Menempatkan null pada SelectionReducer adalah sebagai default pada saat aplikasi start tidak ada item yang ter-seleksi. 599 | 600 | Pada file reducers/index.js, import SelectionReducer (to wire up) 601 | 602 | import SelectionReducer from './SelectionReducer'; 603 | 604 | dan 605 | 606 | selectedLibraryId: SelectionReducer 607 | 608 | Menjadi: 609 | 610 | export default combineReducers({ 611 | libraries: LibraryReducer, 612 | selectedLibraryId: SelectionReducer 613 | }); 614 | 615 | ### Action Creator 616 | 617 | Action Creator adalah JS function -> return action (*Action Creator is a function that return an Action*) 618 | 619 | **Component -> Action Creator -> Action -> Reducer** 620 | 621 | - Buat folder baru Actions dibawah folder src, 622 | - Buat file baru index.js 623 | 624 | Pada index.js sebagai Action Creator buat plain function sbb: 625 | 626 | export const selectLibrary = () => { 627 | 628 | }; 629 | 630 | dan mereturn sebuah Action: 631 | 632 | return { 633 | type: 'select_library' 634 | }; 635 | 636 | menjadi: 637 | 638 | export const selectLibrary = () => { 639 | return { 640 | type: 'select_library' 641 | }; 642 | }; 643 | 644 | Kemudian lewatkan libraryId sebagai argumen menjadi sbb: 645 | 646 | export const selectLibrary = (libraryId) => { 647 | return { 648 | type: 'select_library', 649 | payload: libraryId 650 | }; 651 | }; 652 | 653 | #### Cara memanggil Action Creator 654 | 655 | Memanggil Action Creator di file ListItem.js, pada saat user klik item maka item tersebut akan terseleksi. 656 | 657 | **import Action Creator ke dalam ListItem.js**: 658 | 659 | import * as actions from '../actions'; // .. karena dari lokasi saat ini lompat ke direktori actions 660 | 661 | **import connect dari react-redux** 662 | 663 | import { connect } from 'react-redux'; 664 | 665 | **Update export default statement dengan connect helper** 666 | 667 | export default connect()(ListItem); 668 | 669 | **Catatan**: *connect helper mempunyai 2 buah argument, pertama melewatkan mapStateToProps, kedua melewatkan seluruh actions object. Karena kita tidak memiliki mapStateToProps disini maka argumen pertama isi dengan **null***. 670 | 671 | export default connect(null, actions)(ListItem); 672 | 673 | **Test dengan console.log** 674 | 675 | render() { 676 | const {titleStyle} = styles; 677 | console.log(this.props); 678 | ... 679 | 680 | ![console-log-select](http://res.cloudinary.com/medioxtra/image/upload/c_scale,h_300,w_600/v1496464602/console-log-select_ggycpr.png) 681 | 682 | **Menambahkan Component TouchableWithoutFeedback & View** 683 | 684 | import { Text, TouchableWithoutFeedback, View } from 'react-native'; 685 | 686 | **Update component menjadi sbb:** 687 | 688 | this.props.selectLibrary(id)} 690 | > 691 | 692 | 693 | 694 | {this.props.library.title} 695 | 696 | 697 | 698 | 699 | 700 | **Lakukan destructure code** 701 | 702 | const { id, title} = this.props.library; 703 | 704 | Menjadi: 705 | 706 | class ListItem extends Component { 707 | render() { 708 | const {titleStyle} = styles; 709 | const { id, title } = this.props.library; 710 | 711 | return( 712 | this.props.selectLibrary(id)} 714 | > 715 | 716 | 717 | 718 | {title} 719 | 720 | 721 | 722 | 723 | ); 724 | } 725 | } 726 | 727 | **Pada file SelectionReducer.js test dengan console.log dan tambahkan argumen reducer** 728 | 729 | export default (state, action) => { 730 | console.log(action); 731 | return null; 732 | }; 733 | 734 | ![consolelog-select-id](http://res.cloudinary.com/medioxtra/image/upload/c_scale,h_320,w_800/v1496472223/console-log-select-id_xz51od.png) 735 | 736 | **Menambahkan switch** 737 | 738 | Setiap reducer yang kita buat memiliki statement switch di dalamnya, sebagai condition statement: 739 | 740 | export default (state = null, action) => { 741 | switch (action.type) { 742 | case 'select_library': 743 | return action.payload; 744 | default: 745 | return state; 746 | } 747 | }; 748 | 749 | ### Expanding Row 750 | 751 | Pada file ListItem.js sekarang saatnya menambahkan mapStateToProps: 752 | 753 | const mapStateToProps = state => { 754 | return { selectedLibraryId: state.selectedLibraryId } 755 | }; 756 | 757 | Lewatkan mapStateToProps pada connect statement: 758 | 759 | export default connect(mapStateToProps, actions)(ListItem); 760 | 761 | Tambahkan helper method renderDescription: 762 | 763 | renderDescription() { 764 | if (this.props.library.id === this.props.selectedLibraryId ) { 765 | return ( 766 | {this.props.library.description} 767 | ); 768 | } 769 | }; 770 | 771 | Destructure: 772 | 773 | const { library, selectedLibraryId } = this.props 774 | 775 | Panggil method renderDescription pada render method: 776 | 777 | {this.renderDescription()}; 778 | 779 | menjadi: 780 | 781 | 782 | 783 | 784 | {title} 785 | 786 | 787 | {this.renderDescription()} 788 | 789 | 790 | ### Refactor the Code! 791 | 792 | Update mapStateToProps menjadi sbb : 793 | 794 | const mapStateToProps = (state, ownProps) => { 795 | const expanded = state.selectedLibraryId === ownProps.library.id; 796 | 797 | return { expanded } 798 | }; 799 | 800 | Update renderDescription: 801 | 802 | renderDescription() { 803 | const { library, expanded } = this.props; 804 | 805 | if (expanded) { 806 | return ( 807 | {library.description} 808 | ); 809 | } 810 | }; 811 | 812 | Refresh the browser 813 | 814 | #### Stylish 815 | 816 | 817 | {library.description} 818 | 819 | 820 | #### Menambahkan Layout Animation 821 | 822 | import {..., LayoutAnimation} from 'react-native' 823 | 824 | Tambahkan lifecycle method 825 | 826 | class ListItem extends Component { 827 | componentWillUpdate() { 828 | LayoutAnimation.spring(); 829 | } 830 | 831 | Refresh Screen 832 | 833 | ![finish](http://res.cloudinary.com/medioxtra/image/upload/c_scale,h_600,w_300/v1496580861/finish_mfqxwy.png) 834 | 835 | Selesai Terimakasih :) 836 | 837 | Kritik & Saran ke: jsp.dio@gmail.com 838 | 839 | Privat & Training Kelas ke WA: 0878 788 669 43 840 | -------------------------------------------------------------------------------- /ios/technology_stack.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; }; 11 | 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; }; 12 | 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; }; 13 | 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; }; 14 | 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; }; 15 | 00E356F31AD99517003FC87E /* technology_stackTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* technology_stackTests.m */; }; 16 | 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; }; 17 | 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; }; 18 | 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; }; 19 | 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 20 | 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 21 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 22 | 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 23 | 140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 24 | 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 25 | 2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 26 | 2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 27 | 2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 28 | 2D02E4C21E0B4AEC006451C7 /* libRCTAnimation-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */; }; 29 | 2D02E4C31E0B4AEC006451C7 /* libRCTImage-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */; }; 30 | 2D02E4C41E0B4AEC006451C7 /* libRCTLinking-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */; }; 31 | 2D02E4C51E0B4AEC006451C7 /* libRCTNetwork-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */; }; 32 | 2D02E4C61E0B4AEC006451C7 /* libRCTSettings-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */; }; 33 | 2D02E4C71E0B4AEC006451C7 /* libRCTText-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */; }; 34 | 2D02E4C81E0B4AEC006451C7 /* libRCTWebSocket-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */; }; 35 | 2D02E4C91E0B4AEC006451C7 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3EA31DF850E9000B6D8A /* libReact.a */; }; 36 | 2DCD954D1E0B4F2C00145EB5 /* technology_stackTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* technology_stackTests.m */; }; 37 | 5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */; }; 38 | 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; 39 | /* End PBXBuildFile section */ 40 | 41 | /* Begin PBXContainerItemProxy section */ 42 | 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */ = { 43 | isa = PBXContainerItemProxy; 44 | containerPortal = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; 45 | proxyType = 2; 46 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 47 | remoteInfo = RCTActionSheet; 48 | }; 49 | 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */ = { 50 | isa = PBXContainerItemProxy; 51 | containerPortal = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; 52 | proxyType = 2; 53 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 54 | remoteInfo = RCTGeolocation; 55 | }; 56 | 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */ = { 57 | isa = PBXContainerItemProxy; 58 | containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; 59 | proxyType = 2; 60 | remoteGlobalIDString = 58B5115D1A9E6B3D00147676; 61 | remoteInfo = RCTImage; 62 | }; 63 | 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */ = { 64 | isa = PBXContainerItemProxy; 65 | containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; 66 | proxyType = 2; 67 | remoteGlobalIDString = 58B511DB1A9E6C8500147676; 68 | remoteInfo = RCTNetwork; 69 | }; 70 | 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */ = { 71 | isa = PBXContainerItemProxy; 72 | containerPortal = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; 73 | proxyType = 2; 74 | remoteGlobalIDString = 832C81801AAF6DEF007FA2F7; 75 | remoteInfo = RCTVibration; 76 | }; 77 | 00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = { 78 | isa = PBXContainerItemProxy; 79 | containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; 80 | proxyType = 1; 81 | remoteGlobalIDString = 13B07F861A680F5B00A75B9A; 82 | remoteInfo = technology_stack; 83 | }; 84 | 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = { 85 | isa = PBXContainerItemProxy; 86 | containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; 87 | proxyType = 2; 88 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 89 | remoteInfo = RCTSettings; 90 | }; 91 | 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */ = { 92 | isa = PBXContainerItemProxy; 93 | containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; 94 | proxyType = 2; 95 | remoteGlobalIDString = 3C86DF461ADF2C930047B81A; 96 | remoteInfo = RCTWebSocket; 97 | }; 98 | 146834031AC3E56700842450 /* PBXContainerItemProxy */ = { 99 | isa = PBXContainerItemProxy; 100 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 101 | proxyType = 2; 102 | remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192; 103 | remoteInfo = React; 104 | }; 105 | 2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */ = { 106 | isa = PBXContainerItemProxy; 107 | containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; 108 | proxyType = 1; 109 | remoteGlobalIDString = 2D02E47A1E0B4A5D006451C7; 110 | remoteInfo = "technology_stack-tvOS"; 111 | }; 112 | 3DAD3E831DF850E9000B6D8A /* PBXContainerItemProxy */ = { 113 | isa = PBXContainerItemProxy; 114 | containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; 115 | proxyType = 2; 116 | remoteGlobalIDString = 2D2A283A1D9B042B00D4039D; 117 | remoteInfo = "RCTImage-tvOS"; 118 | }; 119 | 3DAD3E871DF850E9000B6D8A /* PBXContainerItemProxy */ = { 120 | isa = PBXContainerItemProxy; 121 | containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; 122 | proxyType = 2; 123 | remoteGlobalIDString = 2D2A28471D9B043800D4039D; 124 | remoteInfo = "RCTLinking-tvOS"; 125 | }; 126 | 3DAD3E8B1DF850E9000B6D8A /* PBXContainerItemProxy */ = { 127 | isa = PBXContainerItemProxy; 128 | containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; 129 | proxyType = 2; 130 | remoteGlobalIDString = 2D2A28541D9B044C00D4039D; 131 | remoteInfo = "RCTNetwork-tvOS"; 132 | }; 133 | 3DAD3E8F1DF850E9000B6D8A /* PBXContainerItemProxy */ = { 134 | isa = PBXContainerItemProxy; 135 | containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; 136 | proxyType = 2; 137 | remoteGlobalIDString = 2D2A28611D9B046600D4039D; 138 | remoteInfo = "RCTSettings-tvOS"; 139 | }; 140 | 3DAD3E931DF850E9000B6D8A /* PBXContainerItemProxy */ = { 141 | isa = PBXContainerItemProxy; 142 | containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; 143 | proxyType = 2; 144 | remoteGlobalIDString = 2D2A287B1D9B048500D4039D; 145 | remoteInfo = "RCTText-tvOS"; 146 | }; 147 | 3DAD3E981DF850E9000B6D8A /* PBXContainerItemProxy */ = { 148 | isa = PBXContainerItemProxy; 149 | containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; 150 | proxyType = 2; 151 | remoteGlobalIDString = 2D2A28881D9B049200D4039D; 152 | remoteInfo = "RCTWebSocket-tvOS"; 153 | }; 154 | 3DAD3EA21DF850E9000B6D8A /* PBXContainerItemProxy */ = { 155 | isa = PBXContainerItemProxy; 156 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 157 | proxyType = 2; 158 | remoteGlobalIDString = 2D2A28131D9B038B00D4039D; 159 | remoteInfo = "React-tvOS"; 160 | }; 161 | 3DAD3EA41DF850E9000B6D8A /* PBXContainerItemProxy */ = { 162 | isa = PBXContainerItemProxy; 163 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 164 | proxyType = 2; 165 | remoteGlobalIDString = 3D3C059A1DE3340900C268FA; 166 | remoteInfo = yoga; 167 | }; 168 | 3DAD3EA61DF850E9000B6D8A /* PBXContainerItemProxy */ = { 169 | isa = PBXContainerItemProxy; 170 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 171 | proxyType = 2; 172 | remoteGlobalIDString = 3D3C06751DE3340C00C268FA; 173 | remoteInfo = "yoga-tvOS"; 174 | }; 175 | 3DAD3EA81DF850E9000B6D8A /* PBXContainerItemProxy */ = { 176 | isa = PBXContainerItemProxy; 177 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 178 | proxyType = 2; 179 | remoteGlobalIDString = 3D3CD9251DE5FBEC00167DC4; 180 | remoteInfo = cxxreact; 181 | }; 182 | 3DAD3EAA1DF850E9000B6D8A /* PBXContainerItemProxy */ = { 183 | isa = PBXContainerItemProxy; 184 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 185 | proxyType = 2; 186 | remoteGlobalIDString = 3D3CD9321DE5FBEE00167DC4; 187 | remoteInfo = "cxxreact-tvOS"; 188 | }; 189 | 3DAD3EAC1DF850E9000B6D8A /* PBXContainerItemProxy */ = { 190 | isa = PBXContainerItemProxy; 191 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 192 | proxyType = 2; 193 | remoteGlobalIDString = 3D3CD90B1DE5FBD600167DC4; 194 | remoteInfo = jschelpers; 195 | }; 196 | 3DAD3EAE1DF850E9000B6D8A /* PBXContainerItemProxy */ = { 197 | isa = PBXContainerItemProxy; 198 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 199 | proxyType = 2; 200 | remoteGlobalIDString = 3D3CD9181DE5FBD800167DC4; 201 | remoteInfo = "jschelpers-tvOS"; 202 | }; 203 | 5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */ = { 204 | isa = PBXContainerItemProxy; 205 | containerPortal = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */; 206 | proxyType = 2; 207 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 208 | remoteInfo = RCTAnimation; 209 | }; 210 | 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */ = { 211 | isa = PBXContainerItemProxy; 212 | containerPortal = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */; 213 | proxyType = 2; 214 | remoteGlobalIDString = 2D2A28201D9B03D100D4039D; 215 | remoteInfo = "RCTAnimation-tvOS"; 216 | }; 217 | 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = { 218 | isa = PBXContainerItemProxy; 219 | containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; 220 | proxyType = 2; 221 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 222 | remoteInfo = RCTLinking; 223 | }; 224 | 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = { 225 | isa = PBXContainerItemProxy; 226 | containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; 227 | proxyType = 2; 228 | remoteGlobalIDString = 58B5119B1A9E6C1200147676; 229 | remoteInfo = RCTText; 230 | }; 231 | /* End PBXContainerItemProxy section */ 232 | 233 | /* Begin PBXFileReference section */ 234 | 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; }; 235 | 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = ""; }; 236 | 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = "../node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj"; sourceTree = ""; }; 237 | 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = ""; }; 238 | 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = ""; }; 239 | 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = ""; }; 240 | 00E356EE1AD99517003FC87E /* technology_stackTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = technology_stackTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 241 | 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 242 | 00E356F21AD99517003FC87E /* technology_stackTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = technology_stackTests.m; sourceTree = ""; }; 243 | 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = ""; }; 244 | 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = ""; }; 245 | 13B07F961A680F5B00A75B9A /* technology_stack.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = technology_stack.app; sourceTree = BUILT_PRODUCTS_DIR; }; 246 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = technology_stack/AppDelegate.h; sourceTree = ""; }; 247 | 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = technology_stack/AppDelegate.m; sourceTree = ""; }; 248 | 13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 249 | 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = technology_stack/Images.xcassets; sourceTree = ""; }; 250 | 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = technology_stack/Info.plist; sourceTree = ""; }; 251 | 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = technology_stack/main.m; sourceTree = ""; }; 252 | 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = ""; }; 253 | 2D02E47B1E0B4A5D006451C7 /* technology_stack-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "technology_stack-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 254 | 2D02E4901E0B4A5D006451C7 /* technology_stack-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "technology_stack-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 255 | 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = "../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"; sourceTree = ""; }; 256 | 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; }; 257 | 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; }; 258 | /* End PBXFileReference section */ 259 | 260 | /* Begin PBXFrameworksBuildPhase section */ 261 | 00E356EB1AD99517003FC87E /* Frameworks */ = { 262 | isa = PBXFrameworksBuildPhase; 263 | buildActionMask = 2147483647; 264 | files = ( 265 | 140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */, 266 | ); 267 | runOnlyForDeploymentPostprocessing = 0; 268 | }; 269 | 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { 270 | isa = PBXFrameworksBuildPhase; 271 | buildActionMask = 2147483647; 272 | files = ( 273 | 146834051AC3E58100842450 /* libReact.a in Frameworks */, 274 | 5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */, 275 | 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, 276 | 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */, 277 | 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */, 278 | 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */, 279 | 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */, 280 | 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */, 281 | 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */, 282 | 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */, 283 | 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */, 284 | ); 285 | runOnlyForDeploymentPostprocessing = 0; 286 | }; 287 | 2D02E4781E0B4A5D006451C7 /* Frameworks */ = { 288 | isa = PBXFrameworksBuildPhase; 289 | buildActionMask = 2147483647; 290 | files = ( 291 | 2D02E4C91E0B4AEC006451C7 /* libReact.a in Frameworks */, 292 | 2D02E4C21E0B4AEC006451C7 /* libRCTAnimation-tvOS.a in Frameworks */, 293 | 2D02E4C31E0B4AEC006451C7 /* libRCTImage-tvOS.a in Frameworks */, 294 | 2D02E4C41E0B4AEC006451C7 /* libRCTLinking-tvOS.a in Frameworks */, 295 | 2D02E4C51E0B4AEC006451C7 /* libRCTNetwork-tvOS.a in Frameworks */, 296 | 2D02E4C61E0B4AEC006451C7 /* libRCTSettings-tvOS.a in Frameworks */, 297 | 2D02E4C71E0B4AEC006451C7 /* libRCTText-tvOS.a in Frameworks */, 298 | 2D02E4C81E0B4AEC006451C7 /* libRCTWebSocket-tvOS.a in Frameworks */, 299 | ); 300 | runOnlyForDeploymentPostprocessing = 0; 301 | }; 302 | 2D02E48D1E0B4A5D006451C7 /* Frameworks */ = { 303 | isa = PBXFrameworksBuildPhase; 304 | buildActionMask = 2147483647; 305 | files = ( 306 | ); 307 | runOnlyForDeploymentPostprocessing = 0; 308 | }; 309 | /* End PBXFrameworksBuildPhase section */ 310 | 311 | /* Begin PBXGroup section */ 312 | 00C302A81ABCB8CE00DB3ED1 /* Products */ = { 313 | isa = PBXGroup; 314 | children = ( 315 | 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */, 316 | ); 317 | name = Products; 318 | sourceTree = ""; 319 | }; 320 | 00C302B61ABCB90400DB3ED1 /* Products */ = { 321 | isa = PBXGroup; 322 | children = ( 323 | 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */, 324 | ); 325 | name = Products; 326 | sourceTree = ""; 327 | }; 328 | 00C302BC1ABCB91800DB3ED1 /* Products */ = { 329 | isa = PBXGroup; 330 | children = ( 331 | 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */, 332 | 3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */, 333 | ); 334 | name = Products; 335 | sourceTree = ""; 336 | }; 337 | 00C302D41ABCB9D200DB3ED1 /* Products */ = { 338 | isa = PBXGroup; 339 | children = ( 340 | 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */, 341 | 3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */, 342 | ); 343 | name = Products; 344 | sourceTree = ""; 345 | }; 346 | 00C302E01ABCB9EE00DB3ED1 /* Products */ = { 347 | isa = PBXGroup; 348 | children = ( 349 | 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */, 350 | ); 351 | name = Products; 352 | sourceTree = ""; 353 | }; 354 | 00E356EF1AD99517003FC87E /* technology_stackTests */ = { 355 | isa = PBXGroup; 356 | children = ( 357 | 00E356F21AD99517003FC87E /* technology_stackTests.m */, 358 | 00E356F01AD99517003FC87E /* Supporting Files */, 359 | ); 360 | path = technology_stackTests; 361 | sourceTree = ""; 362 | }; 363 | 00E356F01AD99517003FC87E /* Supporting Files */ = { 364 | isa = PBXGroup; 365 | children = ( 366 | 00E356F11AD99517003FC87E /* Info.plist */, 367 | ); 368 | name = "Supporting Files"; 369 | sourceTree = ""; 370 | }; 371 | 139105B71AF99BAD00B5F7CC /* Products */ = { 372 | isa = PBXGroup; 373 | children = ( 374 | 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */, 375 | 3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */, 376 | ); 377 | name = Products; 378 | sourceTree = ""; 379 | }; 380 | 139FDEE71B06529A00C62182 /* Products */ = { 381 | isa = PBXGroup; 382 | children = ( 383 | 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */, 384 | 3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */, 385 | ); 386 | name = Products; 387 | sourceTree = ""; 388 | }; 389 | 13B07FAE1A68108700A75B9A /* technology_stack */ = { 390 | isa = PBXGroup; 391 | children = ( 392 | 008F07F21AC5B25A0029DE68 /* main.jsbundle */, 393 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */, 394 | 13B07FB01A68108700A75B9A /* AppDelegate.m */, 395 | 13B07FB51A68108700A75B9A /* Images.xcassets */, 396 | 13B07FB61A68108700A75B9A /* Info.plist */, 397 | 13B07FB11A68108700A75B9A /* LaunchScreen.xib */, 398 | 13B07FB71A68108700A75B9A /* main.m */, 399 | ); 400 | name = technology_stack; 401 | sourceTree = ""; 402 | }; 403 | 146834001AC3E56700842450 /* Products */ = { 404 | isa = PBXGroup; 405 | children = ( 406 | 146834041AC3E56700842450 /* libReact.a */, 407 | 3DAD3EA31DF850E9000B6D8A /* libReact.a */, 408 | 3DAD3EA51DF850E9000B6D8A /* libyoga.a */, 409 | 3DAD3EA71DF850E9000B6D8A /* libyoga.a */, 410 | 3DAD3EA91DF850E9000B6D8A /* libcxxreact.a */, 411 | 3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */, 412 | 3DAD3EAD1DF850E9000B6D8A /* libjschelpers.a */, 413 | 3DAD3EAF1DF850E9000B6D8A /* libjschelpers.a */, 414 | ); 415 | name = Products; 416 | sourceTree = ""; 417 | }; 418 | 5E91572E1DD0AC6500FF2AA8 /* Products */ = { 419 | isa = PBXGroup; 420 | children = ( 421 | 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */, 422 | 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */, 423 | ); 424 | name = Products; 425 | sourceTree = ""; 426 | }; 427 | 78C398B11ACF4ADC00677621 /* Products */ = { 428 | isa = PBXGroup; 429 | children = ( 430 | 78C398B91ACF4ADC00677621 /* libRCTLinking.a */, 431 | 3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */, 432 | ); 433 | name = Products; 434 | sourceTree = ""; 435 | }; 436 | 832341AE1AAA6A7D00B99B32 /* Libraries */ = { 437 | isa = PBXGroup; 438 | children = ( 439 | 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */, 440 | 146833FF1AC3E56700842450 /* React.xcodeproj */, 441 | 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, 442 | 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */, 443 | 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */, 444 | 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */, 445 | 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */, 446 | 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */, 447 | 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */, 448 | 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */, 449 | 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */, 450 | ); 451 | name = Libraries; 452 | sourceTree = ""; 453 | }; 454 | 832341B11AAA6A8300B99B32 /* Products */ = { 455 | isa = PBXGroup; 456 | children = ( 457 | 832341B51AAA6A8300B99B32 /* libRCTText.a */, 458 | 3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */, 459 | ); 460 | name = Products; 461 | sourceTree = ""; 462 | }; 463 | 83CBB9F61A601CBA00E9B192 = { 464 | isa = PBXGroup; 465 | children = ( 466 | 13B07FAE1A68108700A75B9A /* technology_stack */, 467 | 832341AE1AAA6A7D00B99B32 /* Libraries */, 468 | 00E356EF1AD99517003FC87E /* technology_stackTests */, 469 | 83CBBA001A601CBA00E9B192 /* Products */, 470 | ); 471 | indentWidth = 2; 472 | sourceTree = ""; 473 | tabWidth = 2; 474 | }; 475 | 83CBBA001A601CBA00E9B192 /* Products */ = { 476 | isa = PBXGroup; 477 | children = ( 478 | 13B07F961A680F5B00A75B9A /* technology_stack.app */, 479 | 00E356EE1AD99517003FC87E /* technology_stackTests.xctest */, 480 | 2D02E47B1E0B4A5D006451C7 /* technology_stack-tvOS.app */, 481 | 2D02E4901E0B4A5D006451C7 /* technology_stack-tvOSTests.xctest */, 482 | ); 483 | name = Products; 484 | sourceTree = ""; 485 | }; 486 | /* End PBXGroup section */ 487 | 488 | /* Begin PBXNativeTarget section */ 489 | 00E356ED1AD99517003FC87E /* technology_stackTests */ = { 490 | isa = PBXNativeTarget; 491 | buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "technology_stackTests" */; 492 | buildPhases = ( 493 | 00E356EA1AD99517003FC87E /* Sources */, 494 | 00E356EB1AD99517003FC87E /* Frameworks */, 495 | 00E356EC1AD99517003FC87E /* Resources */, 496 | ); 497 | buildRules = ( 498 | ); 499 | dependencies = ( 500 | 00E356F51AD99517003FC87E /* PBXTargetDependency */, 501 | ); 502 | name = technology_stackTests; 503 | productName = technology_stackTests; 504 | productReference = 00E356EE1AD99517003FC87E /* technology_stackTests.xctest */; 505 | productType = "com.apple.product-type.bundle.unit-test"; 506 | }; 507 | 13B07F861A680F5B00A75B9A /* technology_stack */ = { 508 | isa = PBXNativeTarget; 509 | buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "technology_stack" */; 510 | buildPhases = ( 511 | 13B07F871A680F5B00A75B9A /* Sources */, 512 | 13B07F8C1A680F5B00A75B9A /* Frameworks */, 513 | 13B07F8E1A680F5B00A75B9A /* Resources */, 514 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, 515 | ); 516 | buildRules = ( 517 | ); 518 | dependencies = ( 519 | ); 520 | name = technology_stack; 521 | productName = "Hello World"; 522 | productReference = 13B07F961A680F5B00A75B9A /* technology_stack.app */; 523 | productType = "com.apple.product-type.application"; 524 | }; 525 | 2D02E47A1E0B4A5D006451C7 /* technology_stack-tvOS */ = { 526 | isa = PBXNativeTarget; 527 | buildConfigurationList = 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "technology_stack-tvOS" */; 528 | buildPhases = ( 529 | 2D02E4771E0B4A5D006451C7 /* Sources */, 530 | 2D02E4781E0B4A5D006451C7 /* Frameworks */, 531 | 2D02E4791E0B4A5D006451C7 /* Resources */, 532 | 2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */, 533 | ); 534 | buildRules = ( 535 | ); 536 | dependencies = ( 537 | ); 538 | name = "technology_stack-tvOS"; 539 | productName = "technology_stack-tvOS"; 540 | productReference = 2D02E47B1E0B4A5D006451C7 /* technology_stack-tvOS.app */; 541 | productType = "com.apple.product-type.application"; 542 | }; 543 | 2D02E48F1E0B4A5D006451C7 /* technology_stack-tvOSTests */ = { 544 | isa = PBXNativeTarget; 545 | buildConfigurationList = 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "technology_stack-tvOSTests" */; 546 | buildPhases = ( 547 | 2D02E48C1E0B4A5D006451C7 /* Sources */, 548 | 2D02E48D1E0B4A5D006451C7 /* Frameworks */, 549 | 2D02E48E1E0B4A5D006451C7 /* Resources */, 550 | ); 551 | buildRules = ( 552 | ); 553 | dependencies = ( 554 | 2D02E4921E0B4A5D006451C7 /* PBXTargetDependency */, 555 | ); 556 | name = "technology_stack-tvOSTests"; 557 | productName = "technology_stack-tvOSTests"; 558 | productReference = 2D02E4901E0B4A5D006451C7 /* technology_stack-tvOSTests.xctest */; 559 | productType = "com.apple.product-type.bundle.unit-test"; 560 | }; 561 | /* End PBXNativeTarget section */ 562 | 563 | /* Begin PBXProject section */ 564 | 83CBB9F71A601CBA00E9B192 /* Project object */ = { 565 | isa = PBXProject; 566 | attributes = { 567 | LastUpgradeCheck = 0610; 568 | ORGANIZATIONNAME = Facebook; 569 | TargetAttributes = { 570 | 00E356ED1AD99517003FC87E = { 571 | CreatedOnToolsVersion = 6.2; 572 | TestTargetID = 13B07F861A680F5B00A75B9A; 573 | }; 574 | 2D02E47A1E0B4A5D006451C7 = { 575 | CreatedOnToolsVersion = 8.2.1; 576 | ProvisioningStyle = Automatic; 577 | }; 578 | 2D02E48F1E0B4A5D006451C7 = { 579 | CreatedOnToolsVersion = 8.2.1; 580 | ProvisioningStyle = Automatic; 581 | TestTargetID = 2D02E47A1E0B4A5D006451C7; 582 | }; 583 | }; 584 | }; 585 | buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "technology_stack" */; 586 | compatibilityVersion = "Xcode 3.2"; 587 | developmentRegion = English; 588 | hasScannedForEncodings = 0; 589 | knownRegions = ( 590 | en, 591 | Base, 592 | ); 593 | mainGroup = 83CBB9F61A601CBA00E9B192; 594 | productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; 595 | projectDirPath = ""; 596 | projectReferences = ( 597 | { 598 | ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */; 599 | ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; 600 | }, 601 | { 602 | ProductGroup = 5E91572E1DD0AC6500FF2AA8 /* Products */; 603 | ProjectRef = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */; 604 | }, 605 | { 606 | ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */; 607 | ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; 608 | }, 609 | { 610 | ProductGroup = 00C302BC1ABCB91800DB3ED1 /* Products */; 611 | ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; 612 | }, 613 | { 614 | ProductGroup = 78C398B11ACF4ADC00677621 /* Products */; 615 | ProjectRef = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; 616 | }, 617 | { 618 | ProductGroup = 00C302D41ABCB9D200DB3ED1 /* Products */; 619 | ProjectRef = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; 620 | }, 621 | { 622 | ProductGroup = 139105B71AF99BAD00B5F7CC /* Products */; 623 | ProjectRef = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; 624 | }, 625 | { 626 | ProductGroup = 832341B11AAA6A8300B99B32 /* Products */; 627 | ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; 628 | }, 629 | { 630 | ProductGroup = 00C302E01ABCB9EE00DB3ED1 /* Products */; 631 | ProjectRef = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; 632 | }, 633 | { 634 | ProductGroup = 139FDEE71B06529A00C62182 /* Products */; 635 | ProjectRef = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; 636 | }, 637 | { 638 | ProductGroup = 146834001AC3E56700842450 /* Products */; 639 | ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */; 640 | }, 641 | ); 642 | projectRoot = ""; 643 | targets = ( 644 | 13B07F861A680F5B00A75B9A /* technology_stack */, 645 | 00E356ED1AD99517003FC87E /* technology_stackTests */, 646 | 2D02E47A1E0B4A5D006451C7 /* technology_stack-tvOS */, 647 | 2D02E48F1E0B4A5D006451C7 /* technology_stack-tvOSTests */, 648 | ); 649 | }; 650 | /* End PBXProject section */ 651 | 652 | /* Begin PBXReferenceProxy section */ 653 | 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */ = { 654 | isa = PBXReferenceProxy; 655 | fileType = archive.ar; 656 | path = libRCTActionSheet.a; 657 | remoteRef = 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */; 658 | sourceTree = BUILT_PRODUCTS_DIR; 659 | }; 660 | 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */ = { 661 | isa = PBXReferenceProxy; 662 | fileType = archive.ar; 663 | path = libRCTGeolocation.a; 664 | remoteRef = 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */; 665 | sourceTree = BUILT_PRODUCTS_DIR; 666 | }; 667 | 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */ = { 668 | isa = PBXReferenceProxy; 669 | fileType = archive.ar; 670 | path = libRCTImage.a; 671 | remoteRef = 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */; 672 | sourceTree = BUILT_PRODUCTS_DIR; 673 | }; 674 | 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */ = { 675 | isa = PBXReferenceProxy; 676 | fileType = archive.ar; 677 | path = libRCTNetwork.a; 678 | remoteRef = 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */; 679 | sourceTree = BUILT_PRODUCTS_DIR; 680 | }; 681 | 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */ = { 682 | isa = PBXReferenceProxy; 683 | fileType = archive.ar; 684 | path = libRCTVibration.a; 685 | remoteRef = 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */; 686 | sourceTree = BUILT_PRODUCTS_DIR; 687 | }; 688 | 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = { 689 | isa = PBXReferenceProxy; 690 | fileType = archive.ar; 691 | path = libRCTSettings.a; 692 | remoteRef = 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */; 693 | sourceTree = BUILT_PRODUCTS_DIR; 694 | }; 695 | 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */ = { 696 | isa = PBXReferenceProxy; 697 | fileType = archive.ar; 698 | path = libRCTWebSocket.a; 699 | remoteRef = 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */; 700 | sourceTree = BUILT_PRODUCTS_DIR; 701 | }; 702 | 146834041AC3E56700842450 /* libReact.a */ = { 703 | isa = PBXReferenceProxy; 704 | fileType = archive.ar; 705 | path = libReact.a; 706 | remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */; 707 | sourceTree = BUILT_PRODUCTS_DIR; 708 | }; 709 | 3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */ = { 710 | isa = PBXReferenceProxy; 711 | fileType = archive.ar; 712 | path = "libRCTImage-tvOS.a"; 713 | remoteRef = 3DAD3E831DF850E9000B6D8A /* PBXContainerItemProxy */; 714 | sourceTree = BUILT_PRODUCTS_DIR; 715 | }; 716 | 3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */ = { 717 | isa = PBXReferenceProxy; 718 | fileType = archive.ar; 719 | path = "libRCTLinking-tvOS.a"; 720 | remoteRef = 3DAD3E871DF850E9000B6D8A /* PBXContainerItemProxy */; 721 | sourceTree = BUILT_PRODUCTS_DIR; 722 | }; 723 | 3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */ = { 724 | isa = PBXReferenceProxy; 725 | fileType = archive.ar; 726 | path = "libRCTNetwork-tvOS.a"; 727 | remoteRef = 3DAD3E8B1DF850E9000B6D8A /* PBXContainerItemProxy */; 728 | sourceTree = BUILT_PRODUCTS_DIR; 729 | }; 730 | 3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */ = { 731 | isa = PBXReferenceProxy; 732 | fileType = archive.ar; 733 | path = "libRCTSettings-tvOS.a"; 734 | remoteRef = 3DAD3E8F1DF850E9000B6D8A /* PBXContainerItemProxy */; 735 | sourceTree = BUILT_PRODUCTS_DIR; 736 | }; 737 | 3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */ = { 738 | isa = PBXReferenceProxy; 739 | fileType = archive.ar; 740 | path = "libRCTText-tvOS.a"; 741 | remoteRef = 3DAD3E931DF850E9000B6D8A /* PBXContainerItemProxy */; 742 | sourceTree = BUILT_PRODUCTS_DIR; 743 | }; 744 | 3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */ = { 745 | isa = PBXReferenceProxy; 746 | fileType = archive.ar; 747 | path = "libRCTWebSocket-tvOS.a"; 748 | remoteRef = 3DAD3E981DF850E9000B6D8A /* PBXContainerItemProxy */; 749 | sourceTree = BUILT_PRODUCTS_DIR; 750 | }; 751 | 3DAD3EA31DF850E9000B6D8A /* libReact.a */ = { 752 | isa = PBXReferenceProxy; 753 | fileType = archive.ar; 754 | path = libReact.a; 755 | remoteRef = 3DAD3EA21DF850E9000B6D8A /* PBXContainerItemProxy */; 756 | sourceTree = BUILT_PRODUCTS_DIR; 757 | }; 758 | 3DAD3EA51DF850E9000B6D8A /* libyoga.a */ = { 759 | isa = PBXReferenceProxy; 760 | fileType = archive.ar; 761 | path = libyoga.a; 762 | remoteRef = 3DAD3EA41DF850E9000B6D8A /* PBXContainerItemProxy */; 763 | sourceTree = BUILT_PRODUCTS_DIR; 764 | }; 765 | 3DAD3EA71DF850E9000B6D8A /* libyoga.a */ = { 766 | isa = PBXReferenceProxy; 767 | fileType = archive.ar; 768 | path = libyoga.a; 769 | remoteRef = 3DAD3EA61DF850E9000B6D8A /* PBXContainerItemProxy */; 770 | sourceTree = BUILT_PRODUCTS_DIR; 771 | }; 772 | 3DAD3EA91DF850E9000B6D8A /* libcxxreact.a */ = { 773 | isa = PBXReferenceProxy; 774 | fileType = archive.ar; 775 | path = libcxxreact.a; 776 | remoteRef = 3DAD3EA81DF850E9000B6D8A /* PBXContainerItemProxy */; 777 | sourceTree = BUILT_PRODUCTS_DIR; 778 | }; 779 | 3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */ = { 780 | isa = PBXReferenceProxy; 781 | fileType = archive.ar; 782 | path = libcxxreact.a; 783 | remoteRef = 3DAD3EAA1DF850E9000B6D8A /* PBXContainerItemProxy */; 784 | sourceTree = BUILT_PRODUCTS_DIR; 785 | }; 786 | 3DAD3EAD1DF850E9000B6D8A /* libjschelpers.a */ = { 787 | isa = PBXReferenceProxy; 788 | fileType = archive.ar; 789 | path = libjschelpers.a; 790 | remoteRef = 3DAD3EAC1DF850E9000B6D8A /* PBXContainerItemProxy */; 791 | sourceTree = BUILT_PRODUCTS_DIR; 792 | }; 793 | 3DAD3EAF1DF850E9000B6D8A /* libjschelpers.a */ = { 794 | isa = PBXReferenceProxy; 795 | fileType = archive.ar; 796 | path = libjschelpers.a; 797 | remoteRef = 3DAD3EAE1DF850E9000B6D8A /* PBXContainerItemProxy */; 798 | sourceTree = BUILT_PRODUCTS_DIR; 799 | }; 800 | 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */ = { 801 | isa = PBXReferenceProxy; 802 | fileType = archive.ar; 803 | path = libRCTAnimation.a; 804 | remoteRef = 5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */; 805 | sourceTree = BUILT_PRODUCTS_DIR; 806 | }; 807 | 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */ = { 808 | isa = PBXReferenceProxy; 809 | fileType = archive.ar; 810 | path = "libRCTAnimation-tvOS.a"; 811 | remoteRef = 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */; 812 | sourceTree = BUILT_PRODUCTS_DIR; 813 | }; 814 | 78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = { 815 | isa = PBXReferenceProxy; 816 | fileType = archive.ar; 817 | path = libRCTLinking.a; 818 | remoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */; 819 | sourceTree = BUILT_PRODUCTS_DIR; 820 | }; 821 | 832341B51AAA6A8300B99B32 /* libRCTText.a */ = { 822 | isa = PBXReferenceProxy; 823 | fileType = archive.ar; 824 | path = libRCTText.a; 825 | remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */; 826 | sourceTree = BUILT_PRODUCTS_DIR; 827 | }; 828 | /* End PBXReferenceProxy section */ 829 | 830 | /* Begin PBXResourcesBuildPhase section */ 831 | 00E356EC1AD99517003FC87E /* Resources */ = { 832 | isa = PBXResourcesBuildPhase; 833 | buildActionMask = 2147483647; 834 | files = ( 835 | ); 836 | runOnlyForDeploymentPostprocessing = 0; 837 | }; 838 | 13B07F8E1A680F5B00A75B9A /* Resources */ = { 839 | isa = PBXResourcesBuildPhase; 840 | buildActionMask = 2147483647; 841 | files = ( 842 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 843 | 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */, 844 | ); 845 | runOnlyForDeploymentPostprocessing = 0; 846 | }; 847 | 2D02E4791E0B4A5D006451C7 /* Resources */ = { 848 | isa = PBXResourcesBuildPhase; 849 | buildActionMask = 2147483647; 850 | files = ( 851 | 2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */, 852 | ); 853 | runOnlyForDeploymentPostprocessing = 0; 854 | }; 855 | 2D02E48E1E0B4A5D006451C7 /* Resources */ = { 856 | isa = PBXResourcesBuildPhase; 857 | buildActionMask = 2147483647; 858 | files = ( 859 | ); 860 | runOnlyForDeploymentPostprocessing = 0; 861 | }; 862 | /* End PBXResourcesBuildPhase section */ 863 | 864 | /* Begin PBXShellScriptBuildPhase section */ 865 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = { 866 | isa = PBXShellScriptBuildPhase; 867 | buildActionMask = 2147483647; 868 | files = ( 869 | ); 870 | inputPaths = ( 871 | ); 872 | name = "Bundle React Native code and images"; 873 | outputPaths = ( 874 | ); 875 | runOnlyForDeploymentPostprocessing = 0; 876 | shellPath = /bin/sh; 877 | shellScript = "export NODE_BINARY=node\n../node_modules/react-native/packager/react-native-xcode.sh"; 878 | }; 879 | 2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */ = { 880 | isa = PBXShellScriptBuildPhase; 881 | buildActionMask = 2147483647; 882 | files = ( 883 | ); 884 | inputPaths = ( 885 | ); 886 | name = "Bundle React Native Code And Images"; 887 | outputPaths = ( 888 | ); 889 | runOnlyForDeploymentPostprocessing = 0; 890 | shellPath = /bin/sh; 891 | shellScript = "export NODE_BINARY=node\n../node_modules/react-native/packager/react-native-xcode.sh"; 892 | }; 893 | /* End PBXShellScriptBuildPhase section */ 894 | 895 | /* Begin PBXSourcesBuildPhase section */ 896 | 00E356EA1AD99517003FC87E /* Sources */ = { 897 | isa = PBXSourcesBuildPhase; 898 | buildActionMask = 2147483647; 899 | files = ( 900 | 00E356F31AD99517003FC87E /* technology_stackTests.m in Sources */, 901 | ); 902 | runOnlyForDeploymentPostprocessing = 0; 903 | }; 904 | 13B07F871A680F5B00A75B9A /* Sources */ = { 905 | isa = PBXSourcesBuildPhase; 906 | buildActionMask = 2147483647; 907 | files = ( 908 | 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */, 909 | 13B07FC11A68108700A75B9A /* main.m in Sources */, 910 | ); 911 | runOnlyForDeploymentPostprocessing = 0; 912 | }; 913 | 2D02E4771E0B4A5D006451C7 /* Sources */ = { 914 | isa = PBXSourcesBuildPhase; 915 | buildActionMask = 2147483647; 916 | files = ( 917 | 2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */, 918 | 2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */, 919 | ); 920 | runOnlyForDeploymentPostprocessing = 0; 921 | }; 922 | 2D02E48C1E0B4A5D006451C7 /* Sources */ = { 923 | isa = PBXSourcesBuildPhase; 924 | buildActionMask = 2147483647; 925 | files = ( 926 | 2DCD954D1E0B4F2C00145EB5 /* technology_stackTests.m in Sources */, 927 | ); 928 | runOnlyForDeploymentPostprocessing = 0; 929 | }; 930 | /* End PBXSourcesBuildPhase section */ 931 | 932 | /* Begin PBXTargetDependency section */ 933 | 00E356F51AD99517003FC87E /* PBXTargetDependency */ = { 934 | isa = PBXTargetDependency; 935 | target = 13B07F861A680F5B00A75B9A /* technology_stack */; 936 | targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */; 937 | }; 938 | 2D02E4921E0B4A5D006451C7 /* PBXTargetDependency */ = { 939 | isa = PBXTargetDependency; 940 | target = 2D02E47A1E0B4A5D006451C7 /* technology_stack-tvOS */; 941 | targetProxy = 2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */; 942 | }; 943 | /* End PBXTargetDependency section */ 944 | 945 | /* Begin PBXVariantGroup section */ 946 | 13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = { 947 | isa = PBXVariantGroup; 948 | children = ( 949 | 13B07FB21A68108700A75B9A /* Base */, 950 | ); 951 | name = LaunchScreen.xib; 952 | path = technology_stack; 953 | sourceTree = ""; 954 | }; 955 | /* End PBXVariantGroup section */ 956 | 957 | /* Begin XCBuildConfiguration section */ 958 | 00E356F61AD99517003FC87E /* Debug */ = { 959 | isa = XCBuildConfiguration; 960 | buildSettings = { 961 | BUNDLE_LOADER = "$(TEST_HOST)"; 962 | GCC_PREPROCESSOR_DEFINITIONS = ( 963 | "DEBUG=1", 964 | "$(inherited)", 965 | ); 966 | INFOPLIST_FILE = technology_stackTests/Info.plist; 967 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 968 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 969 | OTHER_LDFLAGS = ( 970 | "-ObjC", 971 | "-lc++", 972 | ); 973 | PRODUCT_NAME = "$(TARGET_NAME)"; 974 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/technology_stack.app/technology_stack"; 975 | }; 976 | name = Debug; 977 | }; 978 | 00E356F71AD99517003FC87E /* Release */ = { 979 | isa = XCBuildConfiguration; 980 | buildSettings = { 981 | BUNDLE_LOADER = "$(TEST_HOST)"; 982 | COPY_PHASE_STRIP = NO; 983 | INFOPLIST_FILE = technology_stackTests/Info.plist; 984 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 985 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 986 | OTHER_LDFLAGS = ( 987 | "-ObjC", 988 | "-lc++", 989 | ); 990 | PRODUCT_NAME = "$(TARGET_NAME)"; 991 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/technology_stack.app/technology_stack"; 992 | }; 993 | name = Release; 994 | }; 995 | 13B07F941A680F5B00A75B9A /* Debug */ = { 996 | isa = XCBuildConfiguration; 997 | buildSettings = { 998 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 999 | CURRENT_PROJECT_VERSION = 1; 1000 | DEAD_CODE_STRIPPING = NO; 1001 | INFOPLIST_FILE = technology_stack/Info.plist; 1002 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 1003 | OTHER_LDFLAGS = ( 1004 | "$(inherited)", 1005 | "-ObjC", 1006 | "-lc++", 1007 | ); 1008 | PRODUCT_NAME = technology_stack; 1009 | VERSIONING_SYSTEM = "apple-generic"; 1010 | }; 1011 | name = Debug; 1012 | }; 1013 | 13B07F951A680F5B00A75B9A /* Release */ = { 1014 | isa = XCBuildConfiguration; 1015 | buildSettings = { 1016 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 1017 | CURRENT_PROJECT_VERSION = 1; 1018 | INFOPLIST_FILE = technology_stack/Info.plist; 1019 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 1020 | OTHER_LDFLAGS = ( 1021 | "$(inherited)", 1022 | "-ObjC", 1023 | "-lc++", 1024 | ); 1025 | PRODUCT_NAME = technology_stack; 1026 | VERSIONING_SYSTEM = "apple-generic"; 1027 | }; 1028 | name = Release; 1029 | }; 1030 | 2D02E4971E0B4A5E006451C7 /* Debug */ = { 1031 | isa = XCBuildConfiguration; 1032 | buildSettings = { 1033 | ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; 1034 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 1035 | CLANG_ANALYZER_NONNULL = YES; 1036 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 1037 | CLANG_WARN_INFINITE_RECURSION = YES; 1038 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1039 | DEBUG_INFORMATION_FORMAT = dwarf; 1040 | ENABLE_TESTABILITY = YES; 1041 | GCC_NO_COMMON_BLOCKS = YES; 1042 | INFOPLIST_FILE = "technology_stack-tvOS/Info.plist"; 1043 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 1044 | OTHER_LDFLAGS = ( 1045 | "-ObjC", 1046 | "-lc++", 1047 | ); 1048 | PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.technology_stack-tvOS"; 1049 | PRODUCT_NAME = "$(TARGET_NAME)"; 1050 | SDKROOT = appletvos; 1051 | TARGETED_DEVICE_FAMILY = 3; 1052 | TVOS_DEPLOYMENT_TARGET = 9.2; 1053 | }; 1054 | name = Debug; 1055 | }; 1056 | 2D02E4981E0B4A5E006451C7 /* Release */ = { 1057 | isa = XCBuildConfiguration; 1058 | buildSettings = { 1059 | ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; 1060 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 1061 | CLANG_ANALYZER_NONNULL = YES; 1062 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 1063 | CLANG_WARN_INFINITE_RECURSION = YES; 1064 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1065 | COPY_PHASE_STRIP = NO; 1066 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 1067 | GCC_NO_COMMON_BLOCKS = YES; 1068 | INFOPLIST_FILE = "technology_stack-tvOS/Info.plist"; 1069 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 1070 | OTHER_LDFLAGS = ( 1071 | "-ObjC", 1072 | "-lc++", 1073 | ); 1074 | PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.technology_stack-tvOS"; 1075 | PRODUCT_NAME = "$(TARGET_NAME)"; 1076 | SDKROOT = appletvos; 1077 | TARGETED_DEVICE_FAMILY = 3; 1078 | TVOS_DEPLOYMENT_TARGET = 9.2; 1079 | }; 1080 | name = Release; 1081 | }; 1082 | 2D02E4991E0B4A5E006451C7 /* Debug */ = { 1083 | isa = XCBuildConfiguration; 1084 | buildSettings = { 1085 | BUNDLE_LOADER = "$(TEST_HOST)"; 1086 | CLANG_ANALYZER_NONNULL = YES; 1087 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 1088 | CLANG_WARN_INFINITE_RECURSION = YES; 1089 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1090 | DEBUG_INFORMATION_FORMAT = dwarf; 1091 | ENABLE_TESTABILITY = YES; 1092 | GCC_NO_COMMON_BLOCKS = YES; 1093 | INFOPLIST_FILE = "technology_stack-tvOSTests/Info.plist"; 1094 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1095 | PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.technology_stack-tvOSTests"; 1096 | PRODUCT_NAME = "$(TARGET_NAME)"; 1097 | SDKROOT = appletvos; 1098 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/technology_stack-tvOS.app/technology_stack-tvOS"; 1099 | TVOS_DEPLOYMENT_TARGET = 10.1; 1100 | }; 1101 | name = Debug; 1102 | }; 1103 | 2D02E49A1E0B4A5E006451C7 /* Release */ = { 1104 | isa = XCBuildConfiguration; 1105 | buildSettings = { 1106 | BUNDLE_LOADER = "$(TEST_HOST)"; 1107 | CLANG_ANALYZER_NONNULL = YES; 1108 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 1109 | CLANG_WARN_INFINITE_RECURSION = YES; 1110 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1111 | COPY_PHASE_STRIP = NO; 1112 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 1113 | GCC_NO_COMMON_BLOCKS = YES; 1114 | INFOPLIST_FILE = "technology_stack-tvOSTests/Info.plist"; 1115 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1116 | PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.technology_stack-tvOSTests"; 1117 | PRODUCT_NAME = "$(TARGET_NAME)"; 1118 | SDKROOT = appletvos; 1119 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/technology_stack-tvOS.app/technology_stack-tvOS"; 1120 | TVOS_DEPLOYMENT_TARGET = 10.1; 1121 | }; 1122 | name = Release; 1123 | }; 1124 | 83CBBA201A601CBA00E9B192 /* Debug */ = { 1125 | isa = XCBuildConfiguration; 1126 | buildSettings = { 1127 | ALWAYS_SEARCH_USER_PATHS = NO; 1128 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 1129 | CLANG_CXX_LIBRARY = "libc++"; 1130 | CLANG_ENABLE_MODULES = YES; 1131 | CLANG_ENABLE_OBJC_ARC = YES; 1132 | CLANG_WARN_BOOL_CONVERSION = YES; 1133 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1134 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1135 | CLANG_WARN_EMPTY_BODY = YES; 1136 | CLANG_WARN_ENUM_CONVERSION = YES; 1137 | CLANG_WARN_INT_CONVERSION = YES; 1138 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1139 | CLANG_WARN_UNREACHABLE_CODE = YES; 1140 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1141 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 1142 | COPY_PHASE_STRIP = NO; 1143 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1144 | GCC_C_LANGUAGE_STANDARD = gnu99; 1145 | GCC_DYNAMIC_NO_PIC = NO; 1146 | GCC_OPTIMIZATION_LEVEL = 0; 1147 | GCC_PREPROCESSOR_DEFINITIONS = ( 1148 | "DEBUG=1", 1149 | "$(inherited)", 1150 | ); 1151 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 1152 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1153 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1154 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1155 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1156 | GCC_WARN_UNUSED_FUNCTION = YES; 1157 | GCC_WARN_UNUSED_VARIABLE = YES; 1158 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 1159 | MTL_ENABLE_DEBUG_INFO = YES; 1160 | ONLY_ACTIVE_ARCH = YES; 1161 | SDKROOT = iphoneos; 1162 | }; 1163 | name = Debug; 1164 | }; 1165 | 83CBBA211A601CBA00E9B192 /* Release */ = { 1166 | isa = XCBuildConfiguration; 1167 | buildSettings = { 1168 | ALWAYS_SEARCH_USER_PATHS = NO; 1169 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 1170 | CLANG_CXX_LIBRARY = "libc++"; 1171 | CLANG_ENABLE_MODULES = YES; 1172 | CLANG_ENABLE_OBJC_ARC = YES; 1173 | CLANG_WARN_BOOL_CONVERSION = YES; 1174 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1175 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1176 | CLANG_WARN_EMPTY_BODY = YES; 1177 | CLANG_WARN_ENUM_CONVERSION = YES; 1178 | CLANG_WARN_INT_CONVERSION = YES; 1179 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1180 | CLANG_WARN_UNREACHABLE_CODE = YES; 1181 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1182 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 1183 | COPY_PHASE_STRIP = YES; 1184 | ENABLE_NS_ASSERTIONS = NO; 1185 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1186 | GCC_C_LANGUAGE_STANDARD = gnu99; 1187 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1188 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1189 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1190 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1191 | GCC_WARN_UNUSED_FUNCTION = YES; 1192 | GCC_WARN_UNUSED_VARIABLE = YES; 1193 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 1194 | MTL_ENABLE_DEBUG_INFO = NO; 1195 | SDKROOT = iphoneos; 1196 | VALIDATE_PRODUCT = YES; 1197 | }; 1198 | name = Release; 1199 | }; 1200 | /* End XCBuildConfiguration section */ 1201 | 1202 | /* Begin XCConfigurationList section */ 1203 | 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "technology_stackTests" */ = { 1204 | isa = XCConfigurationList; 1205 | buildConfigurations = ( 1206 | 00E356F61AD99517003FC87E /* Debug */, 1207 | 00E356F71AD99517003FC87E /* Release */, 1208 | ); 1209 | defaultConfigurationIsVisible = 0; 1210 | defaultConfigurationName = Release; 1211 | }; 1212 | 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "technology_stack" */ = { 1213 | isa = XCConfigurationList; 1214 | buildConfigurations = ( 1215 | 13B07F941A680F5B00A75B9A /* Debug */, 1216 | 13B07F951A680F5B00A75B9A /* Release */, 1217 | ); 1218 | defaultConfigurationIsVisible = 0; 1219 | defaultConfigurationName = Release; 1220 | }; 1221 | 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "technology_stack-tvOS" */ = { 1222 | isa = XCConfigurationList; 1223 | buildConfigurations = ( 1224 | 2D02E4971E0B4A5E006451C7 /* Debug */, 1225 | 2D02E4981E0B4A5E006451C7 /* Release */, 1226 | ); 1227 | defaultConfigurationIsVisible = 0; 1228 | defaultConfigurationName = Release; 1229 | }; 1230 | 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "technology_stack-tvOSTests" */ = { 1231 | isa = XCConfigurationList; 1232 | buildConfigurations = ( 1233 | 2D02E4991E0B4A5E006451C7 /* Debug */, 1234 | 2D02E49A1E0B4A5E006451C7 /* Release */, 1235 | ); 1236 | defaultConfigurationIsVisible = 0; 1237 | defaultConfigurationName = Release; 1238 | }; 1239 | 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "technology_stack" */ = { 1240 | isa = XCConfigurationList; 1241 | buildConfigurations = ( 1242 | 83CBBA201A601CBA00E9B192 /* Debug */, 1243 | 83CBBA211A601CBA00E9B192 /* Release */, 1244 | ); 1245 | defaultConfigurationIsVisible = 0; 1246 | defaultConfigurationName = Release; 1247 | }; 1248 | /* End XCConfigurationList section */ 1249 | }; 1250 | rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; 1251 | } 1252 | --------------------------------------------------------------------------------