├── .flowconfig ├── .gitignore ├── App ├── Actions │ └── AppActions.js ├── Api │ └── RssFeedApi.js ├── Constants │ └── AppConstants.js ├── Screens │ ├── EntryDetail.js │ ├── FeedDetail.js │ ├── HomeScreen.js │ └── NewFeed.js └── Stores │ ├── FeedStore.js │ └── LocalStorage.js ├── AppDispatcher.js ├── README.md ├── RssReader.xcodeproj ├── project.pbxproj └── xcshareddata │ └── xcschemes │ └── RssReader.xcscheme ├── RssReaderDemo.gif ├── RssReaderTests ├── Info.plist └── RssReaderTests.m ├── iOS ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj │ └── LaunchScreen.xib ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── NavBarButtonPlus.imageset │ │ ├── Contents.json │ │ └── NavBarButtonPlus@3x.png │ └── NavBarButtonSettings.imageset │ │ ├── Contents.json │ │ └── NavBarButtonSettings@3x.png ├── Info.plist ├── main.jsbundle └── main.m ├── index.ios.js └── package.json /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | 3 | # We fork some components by platform. 4 | .*/*.web.js 5 | .*/*.android.js 6 | 7 | # Some modules have their own node_modules with overlap 8 | .*/node_modules/node-haste/.* 9 | 10 | # Ignore react-tools where there are overlaps, but don't ignore anything that 11 | # react-native relies on 12 | .*/node_modules/react-tools/src/vendor/core/ExecutionEnvironment.js 13 | .*/node_modules/react-tools/src/browser/eventPlugins/ResponderEventPlugin.js 14 | .*/node_modules/react-tools/src/browser/ui/React.js 15 | .*/node_modules/react-tools/src/core/ReactInstanceHandles.js 16 | .*/node_modules/react-tools/src/event/EventPropagators.js 17 | 18 | # Ignore commoner tests 19 | .*/node_modules/react-tools/node_modules/commoner/test/.* 20 | 21 | # See https://github.com/facebook/flow/issues/442 22 | .*/react-tools/node_modules/commoner/lib/reader.js 23 | 24 | # Ignore jest 25 | .*/react-native/node_modules/jest-cli/.* 26 | 27 | [include] 28 | 29 | [libs] 30 | node_modules/react-native/Libraries/react-native/react-native-interface.js 31 | 32 | [options] 33 | module.system=haste 34 | -------------------------------------------------------------------------------- /.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 | # node.js 26 | # 27 | node_modules/ 28 | npm-debug.log 29 | -------------------------------------------------------------------------------- /App/Actions/AppActions.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dispatcher = require('../../AppDispatcher'); 4 | var AppConstants = require('../Constants/AppConstants'); 5 | 6 | module.exports = { 7 | addFeed(feed) { 8 | dispatcher.handleViewAction({ 9 | actionType: AppConstants.ADD_FEED, 10 | data: feed, 11 | }); 12 | }, 13 | removeFeed(feed) { 14 | dispatcher.handleViewAction({ 15 | actionType: AppConstants.REMOVE_FEED, 16 | data: feed, 17 | }); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /App/Api/RssFeedApi.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Api = { 4 | fetchRss(url) { 5 | if (!(/^http:\/\//.test(url))) { 6 | url = "http://" + url; 7 | } 8 | 9 | var GOOGLE_FEED_API_URL = 'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=-1&q='; 10 | var url = GOOGLE_FEED_API_URL + encodeURIComponent(url); 11 | 12 | return fetch(url).then((res) => res.json()); 13 | } 14 | }; 15 | 16 | module.exports = Api; 17 | -------------------------------------------------------------------------------- /App/Constants/AppConstants.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var keyMirror = require('keyMirror'); 4 | 5 | module.exports = keyMirror({ 6 | REMOVE_FEED: true, 7 | ADD_FEED: true, 8 | }); 9 | -------------------------------------------------------------------------------- /App/Screens/EntryDetail.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var React = require('react-native'); 4 | 5 | var { 6 | StyleSheet, 7 | View, 8 | WebView 9 | } = React; 10 | 11 | class EntryDetail extends React.Component { 12 | render() { 13 | return ( 14 | 15 | 21 | 22 | ); 23 | } 24 | }; 25 | 26 | var styles = StyleSheet.create({ 27 | container: { 28 | flex: 1, 29 | flexDirection: 'column', 30 | backgroundColor: 'white', 31 | }, 32 | title: { 33 | paddingTop: 2, 34 | paddingBottom: 3, 35 | paddingRight: 15, 36 | fontWeight: 'bold', 37 | fontSize: 16, 38 | }, 39 | webView: { 40 | }, 41 | }); 42 | 43 | module.exports = EntryDetail; 44 | -------------------------------------------------------------------------------- /App/Screens/FeedDetail.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var React = require('react-native'); 4 | var EntryDetail = require('./EntryDetail'); 5 | 6 | var { 7 | ScrollView, 8 | StyleSheet, 9 | Text, 10 | TouchableHighlight, 11 | View, 12 | } = React; 13 | 14 | 15 | class FeedDetail extends React.Component { 16 | 17 | _showEntryDetails(entry:any) { 18 | this.props.navigator.push({ 19 | component: EntryDetail, 20 | title: entry.title, 21 | passProps: { 22 | entry: entry 23 | } 24 | }) 25 | } 26 | 27 | _renderEntries(entry:any) { 28 | return ( 29 | { this._showEntryDetails(entry) }} > 32 | 33 | 34 | {entry.title} 35 | {new Date(entry.publishedDate).toDateString()} 36 | 37 | 38 | 39 | ); 40 | } 41 | 42 | render() { 43 | return ( 44 | 45 | {this.props.entries.map((entry) => { return this._renderEntries(entry) })} 46 | 47 | ); 48 | } 49 | }; 50 | 51 | var styles = StyleSheet.create({ 52 | scrollView: { 53 | flex: 1, 54 | backgroundColor: '#F5FCFF' 55 | }, 56 | wrapper: { 57 | paddingTop: 20, 58 | paddingBottom: 15, 59 | paddingLeft: 10, 60 | paddingRight: 10, 61 | borderBottomWidth: 1, 62 | borderBottomColor: '#e9e9e9', 63 | }, 64 | title: { 65 | paddingTop: 2, 66 | paddingBottom: 3, 67 | paddingRight: 15, 68 | fontWeight: 'bold', 69 | fontSize: 16, 70 | }, 71 | description: { 72 | color: "#B4AEAE", 73 | fontSize: 12, 74 | marginBottom: 5, 75 | }, 76 | smallText: { 77 | fontSize: 11, 78 | textAlign: 'right', 79 | color: "#B4AEAE", 80 | } 81 | }); 82 | 83 | module.exports = FeedDetail; 84 | -------------------------------------------------------------------------------- /App/Screens/HomeScreen.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Api = require('../Api/RssFeedApi'); 4 | var AppActions = require('../Actions/AppActions'); 5 | var FeedStore = require('../Stores/FeedStore'); 6 | var FeedDetail = require('./FeedDetail'); 7 | var React = require('react-native'); 8 | var _ = require('lodash'); 9 | 10 | var { 11 | ActivityIndicatorIOS, 12 | ActionSheetIOS, 13 | AsyncStorage, 14 | ScrollView, 15 | StyleSheet, 16 | Text, 17 | TouchableHighlight, 18 | View, 19 | } = React; 20 | 21 | var ActionSheetIOS = require('ActionSheetIOS'); 22 | 23 | var BUTTONS = [ 24 | 'Remove Feed', 25 | 'Back', 26 | ]; 27 | 28 | var DESTRUCTIVE_INDEX = 0; 29 | var CANCEL_INDEX = 1; 30 | 31 | class HomeScreen extends React.Component { 32 | constructor(props) { 33 | super(props); 34 | this.state = { 35 | feeds: [], 36 | loading: true, 37 | } 38 | } 39 | 40 | componentWillMount() { 41 | FeedStore.addChangeListener(this._updateFeedsFromStore.bind(this)); 42 | this._updateFeedsFromStore(); 43 | } 44 | 45 | componentWillUnmount() { 46 | FeedStore.removeChangeListener(this._updateFeedsFromStore.bind(this)); 47 | } 48 | 49 | _updateFeedsFromStore() { 50 | this.setState({feeds: FeedStore.getState()}); 51 | } 52 | 53 | _showFeedActionSheet(feed) { 54 | ActionSheetIOS.showActionSheetWithOptions({ 55 | options: BUTTONS, 56 | cancelButtonIndex: CANCEL_INDEX, 57 | destructiveButtonIndex: DESTRUCTIVE_INDEX 58 | }, 59 | (buttonIndex) => { 60 | switch(buttonIndex) { 61 | case 0: 62 | AppActions.removeFeed(feed); 63 | this.props.navigator.pop(); 64 | break; 65 | } 66 | }); 67 | } 68 | 69 | _showFeedDetails(feed:any) { 70 | Api.fetchRss(feed.feedUrl) 71 | .then((res) => { 72 | if(res.responseStatus == 200) { 73 | var entries = res.responseData.feed.entries; 74 | this.props.navigator.push ({ 75 | component: FeedDetail, 76 | title: feed.title, 77 | rightButtonIcon: require('image!NavBarButtonSettings'), 78 | onRightButtonPress: () => {this._showFeedActionSheet(feed)}, 79 | passProps: { 80 | entries: entries 81 | } 82 | }) 83 | } else { 84 | AlertIOS.alert(res.responseDetails); 85 | } 86 | }); 87 | } 88 | 89 | _renderFeed(feed:any) { 90 | return ( 91 | { this._showFeedDetails(feed) }} 94 | key={feed.length}> 95 | 96 | 97 | {feed.title} 98 | 99 | 100 | {feed.description} 101 | {feed.feedUrl} 102 | 103 | 104 | 105 | ); 106 | } 107 | 108 | render() { 109 | return ( 110 | 111 | {this.state.feeds.map((feed) => { return this._renderFeed(feed) })} 112 | 113 | ); 114 | } 115 | }; 116 | 117 | var styles = StyleSheet.create({ 118 | scrollView: { 119 | flex: 1, 120 | backgroundColor: '#F5FCFF' 121 | }, 122 | wrapper: { 123 | paddingTop: 20, 124 | paddingBottom: 15, 125 | paddingLeft: 10, 126 | paddingRight: 10, 127 | borderBottomWidth: 1, 128 | borderBottomColor: '#e9e9e9', 129 | }, 130 | title: { 131 | paddingTop: 2, 132 | paddingBottom: 3, 133 | paddingRight: 15, 134 | fontWeight: 'bold', 135 | fontSize: 16, 136 | }, 137 | description: { 138 | color: "#B4AEAE", 139 | fontSize: 12, 140 | marginBottom: 5, 141 | }, 142 | smallText: { 143 | fontSize: 11, 144 | textAlign: 'right', 145 | color: "#B4AEAE", 146 | } 147 | }); 148 | 149 | module.exports = HomeScreen; 150 | -------------------------------------------------------------------------------- /App/Screens/NewFeed.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var React = require('react-native'); 4 | var Api = require('../Api/RssFeedApi'); 5 | var AppActions = require('../Actions/AppActions'); 6 | var FeedStore = require('../Stores/FeedStore'); 7 | var _ = require('lodash'); 8 | 9 | 10 | var { 11 | AlertIOS, 12 | AsyncStorage, 13 | StyleSheet, 14 | Text, 15 | TextInput, 16 | TouchableHighlight, 17 | View, 18 | } = React; 19 | 20 | var STORAGE_KEY = '@FeedList'; 21 | 22 | class NewFeed extends React.Component{ 23 | constructor(props) { 24 | super(props); 25 | this.state = { 26 | input: '', 27 | isLoading: false 28 | } 29 | } 30 | 31 | _addFeed() { 32 | Api.fetchRss(this.state.input).then((res) => { 33 | if (res.responseStatus == 200) { 34 | var feeds = FeedStore.getState(); 35 | var resFeed = res.responseData.feed; 36 | if(_.find(feeds, _.matchesProperty('feedUrl', resFeed.feedUrl))){ 37 | this.props.navigator.pop(); 38 | AlertIOS.alert('Feeds already in list'); 39 | } else { 40 | this.props.navigator.pop(); 41 | AppActions.addFeed(res.responseData.feed); 42 | } 43 | } else { 44 | AlertIOS.alert(res.responseDetails); 45 | } 46 | }); 47 | } 48 | 49 | render() { 50 | return ( 51 | 52 | this.setState({input: text})}/> 55 | 58 | Add 59 | 60 | 61 | ); 62 | } 63 | }; 64 | 65 | var styles = StyleSheet.create({ 66 | container: { 67 | flex: 1, 68 | flexDirection: 'column', 69 | paddingTop: 80, 70 | backgroundColor: '#F5FCFF', 71 | }, 72 | input: { 73 | height: 40, 74 | padding: 5, 75 | margin: 10, 76 | borderColor: 'gray', 77 | borderWidth: 1 78 | }, 79 | buttonText: { 80 | fontSize: 18, 81 | color: 'white', 82 | alignSelf: 'center' 83 | }, 84 | button: { 85 | height: 45, 86 | flexDirection: 'row', 87 | backgroundColor: '#183E63', 88 | borderColor: 'white', 89 | borderWidth: 1, 90 | marginLeft: 30, 91 | marginRight: 30, 92 | marginBottom: 10, 93 | marginTop: 10, 94 | alignSelf: 'stretch', 95 | justifyContent: 'center' 96 | } 97 | }); 98 | 99 | module.exports = NewFeed; 100 | -------------------------------------------------------------------------------- /App/Stores/FeedStore.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var createStore = require('flux-util').createStore; 4 | var dispatcher = require('../../AppDispatcher'); 5 | var AppConstants = require('../Constants/AppConstants'); 6 | var _ = require('lodash'); 7 | 8 | var _feeds = []; 9 | 10 | var store = createStore({ 11 | 12 | setState(feeds) { 13 | _feeds = (feeds && feeds.slice()) || []; 14 | }, 15 | 16 | getState() { 17 | return _feeds.slice(); 18 | }, 19 | 20 | dispatcherIndex: dispatcher.register((payload) => { 21 | var action = payload.action; 22 | 23 | switch(action.actionType) { 24 | case AppConstants.ADD_FEED: 25 | _feeds.push(_.omit(action.data, 'entries')); 26 | store.emitChange(action); 27 | break; 28 | case AppConstants.REMOVE_FEED: 29 | _feeds.splice(_feeds.indexOf(action.data), 1); 30 | store.emitChange(action); 31 | break; 32 | } 33 | 34 | return true; 35 | }) 36 | }) 37 | 38 | module.exports = store; 39 | -------------------------------------------------------------------------------- /App/Stores/LocalStorage.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var createStore = require('flux-util').createStore; 4 | var dispatcher = require('../../AppDispatcher'); 5 | var AppConstants = require('../Constants/AppConstants'); 6 | var FeedStore = require('./FeedStore'); 7 | 8 | var React = require('react-native'); 9 | var { 10 | AsyncStorage, 11 | AlertIOS, 12 | } = React; 13 | 14 | var KEY = '@FeedList'; 15 | 16 | var store = createStore({ 17 | bootstrap(complete) { 18 | AsyncStorage.getItem(KEY, (error, feeds) => { 19 | if (error) { 20 | console.log('Error getting profile from local storage! ' + error.message); 21 | AlertIOS.alert('error'); 22 | complete(); 23 | } else { 24 | FeedStore.setState(JSON.parse(feeds)); 25 | complete(); 26 | } 27 | }) 28 | }, 29 | 30 | dispatcherIndex: dispatcher.register(function(payload) { 31 | var action = payload.action; 32 | 33 | switch(action.actionType) { 34 | case AppConstants.ADD_FEED: 35 | case AppConstants.REMOVE_FEED: 36 | var feeds = FeedStore.getState(); 37 | AsyncStorage.setItem(KEY, JSON.stringify(feeds), (error) => { 38 | store.emitChange(action); 39 | }); 40 | break; 41 | } 42 | 43 | return true; 44 | }) 45 | }) 46 | 47 | module.exports = store; 48 | -------------------------------------------------------------------------------- /AppDispatcher.js: -------------------------------------------------------------------------------- 1 | module.exports = require('flux-util').createDispatcher(); 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## react-native rss-reader 2 | 3 | Simple feed reader using React Native, Flux & Google Feeds API. 4 | 5 | ![Demo gif](https://github.com/christopherdro/react-native-rss-reader/blob/master/RssReaderDemo.gif) 6 | 7 | Special thanks to Brent Vatne for the assistance! -------------------------------------------------------------------------------- /RssReader.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 008F07F31AC5B25A0029DE68 /* main.jsbundle in Resources */ = {isa = PBXBuildFile; fileRef = 008F07F21AC5B25A0029DE68 /* main.jsbundle */; }; 11 | 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; }; 12 | 00C302E61ABCBA2D00DB3ED1 /* libRCTAdSupport.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302B41ABCB8E700DB3ED1 /* libRCTAdSupport.a */; }; 13 | 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; }; 14 | 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; }; 15 | 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; }; 16 | 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; }; 17 | 00E356F31AD99517003FC87E /* RssReaderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* RssReaderTests.m */; }; 18 | 1196BD9C1B0724330094A62A /* RCTSRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 1196BD911B0724330094A62A /* RCTSRWebSocket.m */; }; 19 | 1196BD9D1B0724330094A62A /* RCTWebSocketExecutor.m in Sources */ = {isa = PBXBuildFile; fileRef = 1196BD961B0724330094A62A /* RCTWebSocketExecutor.m */; }; 20 | 1196BD9E1B0724330094A62A /* RCTWebSocketManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1196BD981B0724330094A62A /* RCTWebSocketManager.m */; }; 21 | 1196BD9F1B0724330094A62A /* WebSocket.android.js in Resources */ = {isa = PBXBuildFile; fileRef = 1196BD991B0724330094A62A /* WebSocket.android.js */; }; 22 | 1196BDA01B0724330094A62A /* WebSocket.ios.js in Resources */ = {isa = PBXBuildFile; fileRef = 1196BD9A1B0724330094A62A /* WebSocket.ios.js */; }; 23 | 1196BDA11B0724330094A62A /* WebSocketBase.js in Resources */ = {isa = PBXBuildFile; fileRef = 1196BD9B1B0724330094A62A /* WebSocketBase.js */; }; 24 | 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; }; 25 | 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; }; 26 | 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 27 | 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 28 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 29 | 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 30 | 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 31 | 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; 32 | /* End PBXBuildFile section */ 33 | 34 | /* Begin PBXContainerItemProxy section */ 35 | 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */ = { 36 | isa = PBXContainerItemProxy; 37 | containerPortal = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; 38 | proxyType = 2; 39 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 40 | remoteInfo = RCTActionSheet; 41 | }; 42 | 00C302B31ABCB8E700DB3ED1 /* PBXContainerItemProxy */ = { 43 | isa = PBXContainerItemProxy; 44 | containerPortal = 00C302AF1ABCB8E700DB3ED1 /* RCTAdSupport.xcodeproj */; 45 | proxyType = 2; 46 | remoteGlobalIDString = 832C81801AAF6DEF007FA2F7; 47 | remoteInfo = RCTAdSupport; 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 = RssReader; 83 | }; 84 | 1196BDA31B0724330094A62A /* PBXContainerItemProxy */ = { 85 | isa = PBXContainerItemProxy; 86 | containerPortal = 1196BD921B0724330094A62A /* RCTWebSocket.xcodeproj */; 87 | proxyType = 2; 88 | remoteGlobalIDString = 3C86DF461ADF2C930047B81A; 89 | remoteInfo = RCTWebSocket; 90 | }; 91 | 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = { 92 | isa = PBXContainerItemProxy; 93 | containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; 94 | proxyType = 2; 95 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 96 | remoteInfo = RCTSettings; 97 | }; 98 | 146834031AC3E56700842450 /* PBXContainerItemProxy */ = { 99 | isa = PBXContainerItemProxy; 100 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 101 | proxyType = 2; 102 | remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192; 103 | remoteInfo = React; 104 | }; 105 | 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = { 106 | isa = PBXContainerItemProxy; 107 | containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; 108 | proxyType = 2; 109 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 110 | remoteInfo = RCTLinking; 111 | }; 112 | 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = { 113 | isa = PBXContainerItemProxy; 114 | containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; 115 | proxyType = 2; 116 | remoteGlobalIDString = 58B5119B1A9E6C1200147676; 117 | remoteInfo = RCTText; 118 | }; 119 | /* End PBXContainerItemProxy section */ 120 | 121 | /* Begin PBXFileReference section */ 122 | 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = main.jsbundle; path = iOS/main.jsbundle; sourceTree = ""; }; 123 | 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = ""; }; 124 | 00C302AF1ABCB8E700DB3ED1 /* RCTAdSupport.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAdSupport.xcodeproj; path = "node_modules/react-native/Libraries/AdSupport/RCTAdSupport.xcodeproj"; sourceTree = ""; }; 125 | 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = "node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj"; sourceTree = ""; }; 126 | 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = ""; }; 127 | 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = ""; }; 128 | 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = ""; }; 129 | 00E356EE1AD99517003FC87E /* RssReaderTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RssReaderTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 130 | 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 131 | 00E356F21AD99517003FC87E /* RssReaderTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RssReaderTests.m; sourceTree = ""; }; 132 | 1196BD901B0724330094A62A /* RCTSRWebSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSRWebSocket.h; sourceTree = ""; }; 133 | 1196BD911B0724330094A62A /* RCTSRWebSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSRWebSocket.m; sourceTree = ""; }; 134 | 1196BD921B0724330094A62A /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = RCTWebSocket.xcodeproj; sourceTree = ""; }; 135 | 1196BD951B0724330094A62A /* RCTWebSocketExecutor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWebSocketExecutor.h; sourceTree = ""; }; 136 | 1196BD961B0724330094A62A /* RCTWebSocketExecutor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWebSocketExecutor.m; sourceTree = ""; }; 137 | 1196BD971B0724330094A62A /* RCTWebSocketManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWebSocketManager.h; sourceTree = ""; }; 138 | 1196BD981B0724330094A62A /* RCTWebSocketManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWebSocketManager.m; sourceTree = ""; }; 139 | 1196BD991B0724330094A62A /* WebSocket.android.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = WebSocket.android.js; sourceTree = ""; }; 140 | 1196BD9A1B0724330094A62A /* WebSocket.ios.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = WebSocket.ios.js; sourceTree = ""; }; 141 | 1196BD9B1B0724330094A62A /* WebSocketBase.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = WebSocketBase.js; sourceTree = ""; }; 142 | 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = ""; }; 143 | 13B07F961A680F5B00A75B9A /* RssReader.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RssReader.app; sourceTree = BUILT_PRODUCTS_DIR; }; 144 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = iOS/AppDelegate.h; sourceTree = ""; }; 145 | 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = iOS/AppDelegate.m; sourceTree = ""; }; 146 | 13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 147 | 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = iOS/Images.xcassets; sourceTree = ""; }; 148 | 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = iOS/Info.plist; sourceTree = ""; }; 149 | 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = iOS/main.m; sourceTree = ""; }; 150 | 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "node_modules/react-native/React/React.xcodeproj"; sourceTree = ""; }; 151 | 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; }; 152 | 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; }; 153 | /* End PBXFileReference section */ 154 | 155 | /* Begin PBXFrameworksBuildPhase section */ 156 | 00E356EB1AD99517003FC87E /* Frameworks */ = { 157 | isa = PBXFrameworksBuildPhase; 158 | buildActionMask = 2147483647; 159 | files = ( 160 | ); 161 | runOnlyForDeploymentPostprocessing = 0; 162 | }; 163 | 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { 164 | isa = PBXFrameworksBuildPhase; 165 | buildActionMask = 2147483647; 166 | files = ( 167 | 146834051AC3E58100842450 /* libReact.a in Frameworks */, 168 | 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */, 169 | 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, 170 | 00C302E61ABCBA2D00DB3ED1 /* libRCTAdSupport.a in Frameworks */, 171 | 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */, 172 | 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */, 173 | 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */, 174 | 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */, 175 | 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */, 176 | 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */, 177 | ); 178 | runOnlyForDeploymentPostprocessing = 0; 179 | }; 180 | /* End PBXFrameworksBuildPhase section */ 181 | 182 | /* Begin PBXGroup section */ 183 | 00C302A81ABCB8CE00DB3ED1 /* Products */ = { 184 | isa = PBXGroup; 185 | children = ( 186 | 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */, 187 | ); 188 | name = Products; 189 | sourceTree = ""; 190 | }; 191 | 00C302B01ABCB8E700DB3ED1 /* Products */ = { 192 | isa = PBXGroup; 193 | children = ( 194 | 00C302B41ABCB8E700DB3ED1 /* libRCTAdSupport.a */, 195 | ); 196 | name = Products; 197 | sourceTree = ""; 198 | }; 199 | 00C302B61ABCB90400DB3ED1 /* Products */ = { 200 | isa = PBXGroup; 201 | children = ( 202 | 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */, 203 | ); 204 | name = Products; 205 | sourceTree = ""; 206 | }; 207 | 00C302BC1ABCB91800DB3ED1 /* Products */ = { 208 | isa = PBXGroup; 209 | children = ( 210 | 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */, 211 | ); 212 | name = Products; 213 | sourceTree = ""; 214 | }; 215 | 00C302D41ABCB9D200DB3ED1 /* Products */ = { 216 | isa = PBXGroup; 217 | children = ( 218 | 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */, 219 | ); 220 | name = Products; 221 | sourceTree = ""; 222 | }; 223 | 00C302E01ABCB9EE00DB3ED1 /* Products */ = { 224 | isa = PBXGroup; 225 | children = ( 226 | 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */, 227 | ); 228 | name = Products; 229 | sourceTree = ""; 230 | }; 231 | 00E356EF1AD99517003FC87E /* RssReaderTests */ = { 232 | isa = PBXGroup; 233 | children = ( 234 | 00E356F21AD99517003FC87E /* RssReaderTests.m */, 235 | 00E356F01AD99517003FC87E /* Supporting Files */, 236 | ); 237 | path = RssReaderTests; 238 | sourceTree = ""; 239 | }; 240 | 00E356F01AD99517003FC87E /* Supporting Files */ = { 241 | isa = PBXGroup; 242 | children = ( 243 | 00E356F11AD99517003FC87E /* Info.plist */, 244 | ); 245 | name = "Supporting Files"; 246 | sourceTree = ""; 247 | }; 248 | 1196BD8F1B0724330094A62A /* WebSocket */ = { 249 | isa = PBXGroup; 250 | children = ( 251 | 1196BD901B0724330094A62A /* RCTSRWebSocket.h */, 252 | 1196BD911B0724330094A62A /* RCTSRWebSocket.m */, 253 | 1196BD921B0724330094A62A /* RCTWebSocket.xcodeproj */, 254 | 1196BD951B0724330094A62A /* RCTWebSocketExecutor.h */, 255 | 1196BD961B0724330094A62A /* RCTWebSocketExecutor.m */, 256 | 1196BD971B0724330094A62A /* RCTWebSocketManager.h */, 257 | 1196BD981B0724330094A62A /* RCTWebSocketManager.m */, 258 | 1196BD991B0724330094A62A /* WebSocket.android.js */, 259 | 1196BD9A1B0724330094A62A /* WebSocket.ios.js */, 260 | 1196BD9B1B0724330094A62A /* WebSocketBase.js */, 261 | ); 262 | name = WebSocket; 263 | path = "node_modules/react-native/Libraries/WebSocket"; 264 | sourceTree = ""; 265 | }; 266 | 1196BD931B0724330094A62A /* Products */ = { 267 | isa = PBXGroup; 268 | children = ( 269 | 1196BDA41B0724330094A62A /* libRCTWebSocket.a */, 270 | ); 271 | name = Products; 272 | sourceTree = ""; 273 | }; 274 | 139105B71AF99BAD00B5F7CC /* Products */ = { 275 | isa = PBXGroup; 276 | children = ( 277 | 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */, 278 | ); 279 | name = Products; 280 | sourceTree = ""; 281 | }; 282 | 13B07FAE1A68108700A75B9A /* RssReader */ = { 283 | isa = PBXGroup; 284 | children = ( 285 | 008F07F21AC5B25A0029DE68 /* main.jsbundle */, 286 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */, 287 | 13B07FB01A68108700A75B9A /* AppDelegate.m */, 288 | 13B07FB51A68108700A75B9A /* Images.xcassets */, 289 | 13B07FB61A68108700A75B9A /* Info.plist */, 290 | 13B07FB11A68108700A75B9A /* LaunchScreen.xib */, 291 | 13B07FB71A68108700A75B9A /* main.m */, 292 | ); 293 | name = RssReader; 294 | sourceTree = ""; 295 | }; 296 | 146834001AC3E56700842450 /* Products */ = { 297 | isa = PBXGroup; 298 | children = ( 299 | 146834041AC3E56700842450 /* libReact.a */, 300 | ); 301 | name = Products; 302 | sourceTree = ""; 303 | }; 304 | 78C398B11ACF4ADC00677621 /* Products */ = { 305 | isa = PBXGroup; 306 | children = ( 307 | 78C398B91ACF4ADC00677621 /* libRCTLinking.a */, 308 | ); 309 | name = Products; 310 | sourceTree = ""; 311 | }; 312 | 832341AE1AAA6A7D00B99B32 /* Libraries */ = { 313 | isa = PBXGroup; 314 | children = ( 315 | 1196BD8F1B0724330094A62A /* WebSocket */, 316 | 146833FF1AC3E56700842450 /* React.xcodeproj */, 317 | 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, 318 | 00C302AF1ABCB8E700DB3ED1 /* RCTAdSupport.xcodeproj */, 319 | 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */, 320 | 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */, 321 | 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */, 322 | 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */, 323 | 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */, 324 | 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */, 325 | 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */, 326 | ); 327 | name = Libraries; 328 | sourceTree = ""; 329 | }; 330 | 832341B11AAA6A8300B99B32 /* Products */ = { 331 | isa = PBXGroup; 332 | children = ( 333 | 832341B51AAA6A8300B99B32 /* libRCTText.a */, 334 | ); 335 | name = Products; 336 | sourceTree = ""; 337 | }; 338 | 83CBB9F61A601CBA00E9B192 = { 339 | isa = PBXGroup; 340 | children = ( 341 | 13B07FAE1A68108700A75B9A /* RssReader */, 342 | 832341AE1AAA6A7D00B99B32 /* Libraries */, 343 | 00E356EF1AD99517003FC87E /* RssReaderTests */, 344 | 83CBBA001A601CBA00E9B192 /* Products */, 345 | ); 346 | indentWidth = 2; 347 | sourceTree = ""; 348 | tabWidth = 2; 349 | }; 350 | 83CBBA001A601CBA00E9B192 /* Products */ = { 351 | isa = PBXGroup; 352 | children = ( 353 | 13B07F961A680F5B00A75B9A /* RssReader.app */, 354 | 00E356EE1AD99517003FC87E /* RssReaderTests.xctest */, 355 | ); 356 | name = Products; 357 | sourceTree = ""; 358 | }; 359 | /* End PBXGroup section */ 360 | 361 | /* Begin PBXNativeTarget section */ 362 | 00E356ED1AD99517003FC87E /* RssReaderTests */ = { 363 | isa = PBXNativeTarget; 364 | buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "RssReaderTests" */; 365 | buildPhases = ( 366 | 00E356EA1AD99517003FC87E /* Sources */, 367 | 00E356EB1AD99517003FC87E /* Frameworks */, 368 | 00E356EC1AD99517003FC87E /* Resources */, 369 | ); 370 | buildRules = ( 371 | ); 372 | dependencies = ( 373 | 00E356F51AD99517003FC87E /* PBXTargetDependency */, 374 | ); 375 | name = RssReaderTests; 376 | productName = RssReaderTests; 377 | productReference = 00E356EE1AD99517003FC87E /* RssReaderTests.xctest */; 378 | productType = "com.apple.product-type.bundle.unit-test"; 379 | }; 380 | 13B07F861A680F5B00A75B9A /* RssReader */ = { 381 | isa = PBXNativeTarget; 382 | buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "RssReader" */; 383 | buildPhases = ( 384 | 13B07F871A680F5B00A75B9A /* Sources */, 385 | 13B07F8C1A680F5B00A75B9A /* Frameworks */, 386 | 13B07F8E1A680F5B00A75B9A /* Resources */, 387 | ); 388 | buildRules = ( 389 | ); 390 | dependencies = ( 391 | ); 392 | name = RssReader; 393 | productName = "Hello World"; 394 | productReference = 13B07F961A680F5B00A75B9A /* RssReader.app */; 395 | productType = "com.apple.product-type.application"; 396 | }; 397 | /* End PBXNativeTarget section */ 398 | 399 | /* Begin PBXProject section */ 400 | 83CBB9F71A601CBA00E9B192 /* Project object */ = { 401 | isa = PBXProject; 402 | attributes = { 403 | LastUpgradeCheck = 0610; 404 | ORGANIZATIONNAME = Facebook; 405 | TargetAttributes = { 406 | 00E356ED1AD99517003FC87E = { 407 | CreatedOnToolsVersion = 6.2; 408 | TestTargetID = 13B07F861A680F5B00A75B9A; 409 | }; 410 | }; 411 | }; 412 | buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "RssReader" */; 413 | compatibilityVersion = "Xcode 3.2"; 414 | developmentRegion = English; 415 | hasScannedForEncodings = 0; 416 | knownRegions = ( 417 | en, 418 | Base, 419 | ); 420 | mainGroup = 83CBB9F61A601CBA00E9B192; 421 | productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; 422 | projectDirPath = ""; 423 | projectReferences = ( 424 | { 425 | ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */; 426 | ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; 427 | }, 428 | { 429 | ProductGroup = 00C302B01ABCB8E700DB3ED1 /* Products */; 430 | ProjectRef = 00C302AF1ABCB8E700DB3ED1 /* RCTAdSupport.xcodeproj */; 431 | }, 432 | { 433 | ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */; 434 | ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; 435 | }, 436 | { 437 | ProductGroup = 00C302BC1ABCB91800DB3ED1 /* Products */; 438 | ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; 439 | }, 440 | { 441 | ProductGroup = 78C398B11ACF4ADC00677621 /* Products */; 442 | ProjectRef = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; 443 | }, 444 | { 445 | ProductGroup = 00C302D41ABCB9D200DB3ED1 /* Products */; 446 | ProjectRef = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; 447 | }, 448 | { 449 | ProductGroup = 139105B71AF99BAD00B5F7CC /* Products */; 450 | ProjectRef = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; 451 | }, 452 | { 453 | ProductGroup = 832341B11AAA6A8300B99B32 /* Products */; 454 | ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; 455 | }, 456 | { 457 | ProductGroup = 00C302E01ABCB9EE00DB3ED1 /* Products */; 458 | ProjectRef = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; 459 | }, 460 | { 461 | ProductGroup = 1196BD931B0724330094A62A /* Products */; 462 | ProjectRef = 1196BD921B0724330094A62A /* RCTWebSocket.xcodeproj */; 463 | }, 464 | { 465 | ProductGroup = 146834001AC3E56700842450 /* Products */; 466 | ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */; 467 | }, 468 | ); 469 | projectRoot = ""; 470 | targets = ( 471 | 13B07F861A680F5B00A75B9A /* RssReader */, 472 | 00E356ED1AD99517003FC87E /* RssReaderTests */, 473 | ); 474 | }; 475 | /* End PBXProject section */ 476 | 477 | /* Begin PBXReferenceProxy section */ 478 | 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */ = { 479 | isa = PBXReferenceProxy; 480 | fileType = archive.ar; 481 | path = libRCTActionSheet.a; 482 | remoteRef = 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */; 483 | sourceTree = BUILT_PRODUCTS_DIR; 484 | }; 485 | 00C302B41ABCB8E700DB3ED1 /* libRCTAdSupport.a */ = { 486 | isa = PBXReferenceProxy; 487 | fileType = archive.ar; 488 | path = libRCTAdSupport.a; 489 | remoteRef = 00C302B31ABCB8E700DB3ED1 /* PBXContainerItemProxy */; 490 | sourceTree = BUILT_PRODUCTS_DIR; 491 | }; 492 | 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */ = { 493 | isa = PBXReferenceProxy; 494 | fileType = archive.ar; 495 | path = libRCTGeolocation.a; 496 | remoteRef = 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */; 497 | sourceTree = BUILT_PRODUCTS_DIR; 498 | }; 499 | 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */ = { 500 | isa = PBXReferenceProxy; 501 | fileType = archive.ar; 502 | path = libRCTImage.a; 503 | remoteRef = 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */; 504 | sourceTree = BUILT_PRODUCTS_DIR; 505 | }; 506 | 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */ = { 507 | isa = PBXReferenceProxy; 508 | fileType = archive.ar; 509 | path = libRCTNetwork.a; 510 | remoteRef = 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */; 511 | sourceTree = BUILT_PRODUCTS_DIR; 512 | }; 513 | 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */ = { 514 | isa = PBXReferenceProxy; 515 | fileType = archive.ar; 516 | path = libRCTVibration.a; 517 | remoteRef = 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */; 518 | sourceTree = BUILT_PRODUCTS_DIR; 519 | }; 520 | 1196BDA41B0724330094A62A /* libRCTWebSocket.a */ = { 521 | isa = PBXReferenceProxy; 522 | fileType = archive.ar; 523 | path = libRCTWebSocket.a; 524 | remoteRef = 1196BDA31B0724330094A62A /* PBXContainerItemProxy */; 525 | sourceTree = BUILT_PRODUCTS_DIR; 526 | }; 527 | 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = { 528 | isa = PBXReferenceProxy; 529 | fileType = archive.ar; 530 | path = libRCTSettings.a; 531 | remoteRef = 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */; 532 | sourceTree = BUILT_PRODUCTS_DIR; 533 | }; 534 | 146834041AC3E56700842450 /* libReact.a */ = { 535 | isa = PBXReferenceProxy; 536 | fileType = archive.ar; 537 | path = libReact.a; 538 | remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */; 539 | sourceTree = BUILT_PRODUCTS_DIR; 540 | }; 541 | 78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = { 542 | isa = PBXReferenceProxy; 543 | fileType = archive.ar; 544 | path = libRCTLinking.a; 545 | remoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */; 546 | sourceTree = BUILT_PRODUCTS_DIR; 547 | }; 548 | 832341B51AAA6A8300B99B32 /* libRCTText.a */ = { 549 | isa = PBXReferenceProxy; 550 | fileType = archive.ar; 551 | path = libRCTText.a; 552 | remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */; 553 | sourceTree = BUILT_PRODUCTS_DIR; 554 | }; 555 | /* End PBXReferenceProxy section */ 556 | 557 | /* Begin PBXResourcesBuildPhase section */ 558 | 00E356EC1AD99517003FC87E /* Resources */ = { 559 | isa = PBXResourcesBuildPhase; 560 | buildActionMask = 2147483647; 561 | files = ( 562 | ); 563 | runOnlyForDeploymentPostprocessing = 0; 564 | }; 565 | 13B07F8E1A680F5B00A75B9A /* Resources */ = { 566 | isa = PBXResourcesBuildPhase; 567 | buildActionMask = 2147483647; 568 | files = ( 569 | 1196BDA01B0724330094A62A /* WebSocket.ios.js in Resources */, 570 | 008F07F31AC5B25A0029DE68 /* main.jsbundle in Resources */, 571 | 1196BD9F1B0724330094A62A /* WebSocket.android.js in Resources */, 572 | 1196BDA11B0724330094A62A /* WebSocketBase.js in Resources */, 573 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 574 | 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */, 575 | ); 576 | runOnlyForDeploymentPostprocessing = 0; 577 | }; 578 | /* End PBXResourcesBuildPhase section */ 579 | 580 | /* Begin PBXSourcesBuildPhase section */ 581 | 00E356EA1AD99517003FC87E /* Sources */ = { 582 | isa = PBXSourcesBuildPhase; 583 | buildActionMask = 2147483647; 584 | files = ( 585 | 00E356F31AD99517003FC87E /* RssReaderTests.m in Sources */, 586 | ); 587 | runOnlyForDeploymentPostprocessing = 0; 588 | }; 589 | 13B07F871A680F5B00A75B9A /* Sources */ = { 590 | isa = PBXSourcesBuildPhase; 591 | buildActionMask = 2147483647; 592 | files = ( 593 | 1196BD9D1B0724330094A62A /* RCTWebSocketExecutor.m in Sources */, 594 | 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */, 595 | 13B07FC11A68108700A75B9A /* main.m in Sources */, 596 | 1196BD9E1B0724330094A62A /* RCTWebSocketManager.m in Sources */, 597 | 1196BD9C1B0724330094A62A /* RCTSRWebSocket.m in Sources */, 598 | ); 599 | runOnlyForDeploymentPostprocessing = 0; 600 | }; 601 | /* End PBXSourcesBuildPhase section */ 602 | 603 | /* Begin PBXTargetDependency section */ 604 | 00E356F51AD99517003FC87E /* PBXTargetDependency */ = { 605 | isa = PBXTargetDependency; 606 | target = 13B07F861A680F5B00A75B9A /* RssReader */; 607 | targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */; 608 | }; 609 | /* End PBXTargetDependency section */ 610 | 611 | /* Begin PBXVariantGroup section */ 612 | 13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = { 613 | isa = PBXVariantGroup; 614 | children = ( 615 | 13B07FB21A68108700A75B9A /* Base */, 616 | ); 617 | name = LaunchScreen.xib; 618 | path = iOS; 619 | sourceTree = ""; 620 | }; 621 | /* End PBXVariantGroup section */ 622 | 623 | /* Begin XCBuildConfiguration section */ 624 | 00E356F61AD99517003FC87E /* Debug */ = { 625 | isa = XCBuildConfiguration; 626 | buildSettings = { 627 | BUNDLE_LOADER = "$(TEST_HOST)"; 628 | FRAMEWORK_SEARCH_PATHS = ( 629 | "$(SDKROOT)/Developer/Library/Frameworks", 630 | "$(inherited)", 631 | ); 632 | GCC_PREPROCESSOR_DEFINITIONS = ( 633 | "DEBUG=1", 634 | "$(inherited)", 635 | ); 636 | INFOPLIST_FILE = RssReaderTests/Info.plist; 637 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 638 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 639 | PRODUCT_NAME = "$(TARGET_NAME)"; 640 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RssReader.app/RssReader"; 641 | }; 642 | name = Debug; 643 | }; 644 | 00E356F71AD99517003FC87E /* Release */ = { 645 | isa = XCBuildConfiguration; 646 | buildSettings = { 647 | BUNDLE_LOADER = "$(TEST_HOST)"; 648 | COPY_PHASE_STRIP = NO; 649 | FRAMEWORK_SEARCH_PATHS = ( 650 | "$(SDKROOT)/Developer/Library/Frameworks", 651 | "$(inherited)", 652 | ); 653 | INFOPLIST_FILE = RssReaderTests/Info.plist; 654 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 655 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 656 | PRODUCT_NAME = "$(TARGET_NAME)"; 657 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RssReader.app/RssReader"; 658 | }; 659 | name = Release; 660 | }; 661 | 13B07F941A680F5B00A75B9A /* Debug */ = { 662 | isa = XCBuildConfiguration; 663 | buildSettings = { 664 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 665 | HEADER_SEARCH_PATHS = ( 666 | "$(inherited)", 667 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 668 | "$(SRCROOT)/node_modules/react-native/React/**", 669 | ); 670 | INFOPLIST_FILE = "$(SRCROOT)/iOS/Info.plist"; 671 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 672 | OTHER_LDFLAGS = "-ObjC"; 673 | PRODUCT_NAME = RssReader; 674 | }; 675 | name = Debug; 676 | }; 677 | 13B07F951A680F5B00A75B9A /* Release */ = { 678 | isa = XCBuildConfiguration; 679 | buildSettings = { 680 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 681 | HEADER_SEARCH_PATHS = ( 682 | "$(inherited)", 683 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 684 | "$(SRCROOT)/node_modules/react-native/React/**", 685 | ); 686 | INFOPLIST_FILE = "$(SRCROOT)/iOS/Info.plist"; 687 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 688 | OTHER_LDFLAGS = "-ObjC"; 689 | PRODUCT_NAME = RssReader; 690 | }; 691 | name = Release; 692 | }; 693 | 83CBBA201A601CBA00E9B192 /* Debug */ = { 694 | isa = XCBuildConfiguration; 695 | buildSettings = { 696 | ALWAYS_SEARCH_USER_PATHS = NO; 697 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 698 | CLANG_CXX_LIBRARY = "libc++"; 699 | CLANG_ENABLE_MODULES = YES; 700 | CLANG_ENABLE_OBJC_ARC = YES; 701 | CLANG_WARN_BOOL_CONVERSION = YES; 702 | CLANG_WARN_CONSTANT_CONVERSION = YES; 703 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 704 | CLANG_WARN_EMPTY_BODY = YES; 705 | CLANG_WARN_ENUM_CONVERSION = YES; 706 | CLANG_WARN_INT_CONVERSION = YES; 707 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 708 | CLANG_WARN_UNREACHABLE_CODE = YES; 709 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 710 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 711 | COPY_PHASE_STRIP = NO; 712 | ENABLE_STRICT_OBJC_MSGSEND = YES; 713 | GCC_C_LANGUAGE_STANDARD = gnu99; 714 | GCC_DYNAMIC_NO_PIC = NO; 715 | GCC_OPTIMIZATION_LEVEL = 0; 716 | GCC_PREPROCESSOR_DEFINITIONS = ( 717 | "DEBUG=1", 718 | "$(inherited)", 719 | ); 720 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 721 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 722 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 723 | GCC_WARN_UNDECLARED_SELECTOR = YES; 724 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 725 | GCC_WARN_UNUSED_FUNCTION = YES; 726 | GCC_WARN_UNUSED_VARIABLE = YES; 727 | HEADER_SEARCH_PATHS = ( 728 | "$(inherited)", 729 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 730 | "$(SRCROOT)/node_modules/react-native/React/**", 731 | ); 732 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 733 | MTL_ENABLE_DEBUG_INFO = YES; 734 | ONLY_ACTIVE_ARCH = YES; 735 | SDKROOT = iphoneos; 736 | }; 737 | name = Debug; 738 | }; 739 | 83CBBA211A601CBA00E9B192 /* Release */ = { 740 | isa = XCBuildConfiguration; 741 | buildSettings = { 742 | ALWAYS_SEARCH_USER_PATHS = NO; 743 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 744 | CLANG_CXX_LIBRARY = "libc++"; 745 | CLANG_ENABLE_MODULES = YES; 746 | CLANG_ENABLE_OBJC_ARC = YES; 747 | CLANG_WARN_BOOL_CONVERSION = YES; 748 | CLANG_WARN_CONSTANT_CONVERSION = YES; 749 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 750 | CLANG_WARN_EMPTY_BODY = YES; 751 | CLANG_WARN_ENUM_CONVERSION = YES; 752 | CLANG_WARN_INT_CONVERSION = YES; 753 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 754 | CLANG_WARN_UNREACHABLE_CODE = YES; 755 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 756 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 757 | COPY_PHASE_STRIP = YES; 758 | ENABLE_NS_ASSERTIONS = NO; 759 | ENABLE_STRICT_OBJC_MSGSEND = YES; 760 | GCC_C_LANGUAGE_STANDARD = gnu99; 761 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 762 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 763 | GCC_WARN_UNDECLARED_SELECTOR = YES; 764 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 765 | GCC_WARN_UNUSED_FUNCTION = YES; 766 | GCC_WARN_UNUSED_VARIABLE = YES; 767 | HEADER_SEARCH_PATHS = ( 768 | "$(inherited)", 769 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 770 | "$(SRCROOT)/node_modules/react-native/React/**", 771 | ); 772 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 773 | MTL_ENABLE_DEBUG_INFO = NO; 774 | SDKROOT = iphoneos; 775 | VALIDATE_PRODUCT = YES; 776 | }; 777 | name = Release; 778 | }; 779 | /* End XCBuildConfiguration section */ 780 | 781 | /* Begin XCConfigurationList section */ 782 | 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "RssReaderTests" */ = { 783 | isa = XCConfigurationList; 784 | buildConfigurations = ( 785 | 00E356F61AD99517003FC87E /* Debug */, 786 | 00E356F71AD99517003FC87E /* Release */, 787 | ); 788 | defaultConfigurationIsVisible = 0; 789 | defaultConfigurationName = Release; 790 | }; 791 | 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "RssReader" */ = { 792 | isa = XCConfigurationList; 793 | buildConfigurations = ( 794 | 13B07F941A680F5B00A75B9A /* Debug */, 795 | 13B07F951A680F5B00A75B9A /* Release */, 796 | ); 797 | defaultConfigurationIsVisible = 0; 798 | defaultConfigurationName = Release; 799 | }; 800 | 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "RssReader" */ = { 801 | isa = XCConfigurationList; 802 | buildConfigurations = ( 803 | 83CBBA201A601CBA00E9B192 /* Debug */, 804 | 83CBBA211A601CBA00E9B192 /* Release */, 805 | ); 806 | defaultConfigurationIsVisible = 0; 807 | defaultConfigurationName = Release; 808 | }; 809 | /* End XCConfigurationList section */ 810 | }; 811 | rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; 812 | } 813 | -------------------------------------------------------------------------------- /RssReader.xcodeproj/xcshareddata/xcschemes/RssReader.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 77 | 83 | 84 | 85 | 86 | 87 | 88 | 94 | 96 | 102 | 103 | 104 | 105 | 107 | 108 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /RssReaderDemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/christopherdro/react-native-rss-reader/213e93b3369adf0be0917baab029ba96edb0f244/RssReaderDemo.gif -------------------------------------------------------------------------------- /RssReaderTests/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 | -------------------------------------------------------------------------------- /RssReaderTests/RssReaderTests.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 "RCTAssert.h" 14 | #import "RCTRedBox.h" 15 | #import "RCTRootView.h" 16 | 17 | #define TIMEOUT_SECONDS 240 18 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!" 19 | 20 | @interface RssReaderTests : XCTestCase 21 | 22 | @end 23 | 24 | @implementation RssReaderTests 25 | 26 | 27 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test 28 | { 29 | if (test(view)) { 30 | return YES; 31 | } 32 | for (UIView *subview in [view subviews]) { 33 | if ([self findSubviewInView:subview matching:test]) { 34 | return YES; 35 | } 36 | } 37 | return NO; 38 | } 39 | 40 | - (void)testRendersWelcomeScreen { 41 | UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController]; 42 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 43 | BOOL foundElement = NO; 44 | NSString *redboxError = nil; 45 | 46 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 47 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 48 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 49 | 50 | redboxError = [[RCTRedBox sharedInstance] currentErrorMessage]; 51 | 52 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { 53 | if ([view respondsToSelector:@selector(attributedText)]) { 54 | NSString *text = [(id)view attributedText].string; 55 | if ([text isEqualToString:TEXT_TO_LOOK_FOR]) { 56 | return YES; 57 | } 58 | } 59 | return NO; 60 | }]; 61 | } 62 | 63 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 64 | XCTAssertTrue(foundElement, @"Cound't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 65 | } 66 | 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /iOS/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 | -------------------------------------------------------------------------------- /iOS/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 "RCTRootView.h" 13 | 14 | @implementation AppDelegate 15 | 16 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 17 | { 18 | NSURL *jsCodeLocation; 19 | 20 | /** 21 | * Loading JavaScript code - uncomment the one you want. 22 | * 23 | * OPTION 1 24 | * Load from development server. Start the server from the repository root: 25 | * 26 | * $ npm start 27 | * 28 | * To run on device, change `localhost` to the IP address of your computer 29 | * (you can get this by typing `ifconfig` into the terminal and selecting the 30 | * `inet` value under `en0:`) and make sure your computer and iOS device are 31 | * on the same Wi-Fi network. 32 | */ 33 | 34 | jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle"]; 35 | 36 | /** 37 | * OPTION 2 38 | * Load from pre-bundled file on disk. To re-generate the static bundle 39 | * from the root of your project directory, run 40 | * 41 | * $ react-native bundle --minify 42 | * 43 | * see http://facebook.github.io/react-native/docs/runningondevice.html 44 | */ 45 | 46 | // jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 47 | 48 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 49 | moduleName:@"RssReader" 50 | launchOptions:launchOptions]; 51 | 52 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 53 | UIViewController *rootViewController = [[UIViewController alloc] init]; 54 | rootViewController.view = rootView; 55 | self.window.rootViewController = rootViewController; 56 | [self.window makeKeyAndVisible]; 57 | return YES; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /iOS/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/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/Images.xcassets/NavBarButtonPlus.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "scale" : "3x", 14 | "filename" : "NavBarButtonPlus@3x.png" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /iOS/Images.xcassets/NavBarButtonPlus.imageset/NavBarButtonPlus@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/christopherdro/react-native-rss-reader/213e93b3369adf0be0917baab029ba96edb0f244/iOS/Images.xcassets/NavBarButtonPlus.imageset/NavBarButtonPlus@3x.png -------------------------------------------------------------------------------- /iOS/Images.xcassets/NavBarButtonSettings.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "scale" : "3x", 14 | "filename" : "NavBarButtonSettings@3x.png" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /iOS/Images.xcassets/NavBarButtonSettings.imageset/NavBarButtonSettings@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/christopherdro/react-native-rss-reader/213e93b3369adf0be0917baab029ba96edb0f244/iOS/Images.xcassets/NavBarButtonSettings.imageset/NavBarButtonSettings@3x.png -------------------------------------------------------------------------------- /iOS/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 | 42 | 43 | -------------------------------------------------------------------------------- /iOS/main.jsbundle: -------------------------------------------------------------------------------- 1 | // Offline JS 2 | // To re-generate the offline bundle, run this from the root of your project: 3 | // 4 | // $ react-native bundle --minify 5 | // 6 | // See http://facebook.github.io/react-native/docs/runningondevice.html for more details. 7 | 8 | throw new Error('Offline JS file is empty. See iOS/main.jsbundle for instructions'); 9 | -------------------------------------------------------------------------------- /iOS/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 | -------------------------------------------------------------------------------- /index.ios.js: -------------------------------------------------------------------------------- 1 | /** 2 | * RssReader 3 | * Christopher Dro 4 | */ 5 | 'use strict'; 6 | 7 | 8 | var React = require('react-native'); 9 | var HomeScreen = require('./App/Screens/HomeScreen'); 10 | var NewFeed = require('./App/Screens/NewFeed'); 11 | var LocalStorage = require('./App/Stores/LocalStorage'); 12 | 13 | var { 14 | AlertIOS, 15 | AppRegistry, 16 | AsyncStorage, 17 | NavigatorIOS, 18 | StyleSheet, 19 | Text, 20 | View 21 | } = React; 22 | 23 | class RssReader extends React.Component{ 24 | constructor(props) { 25 | super(props); 26 | this.state = { 27 | bootstrapped: false 28 | } 29 | } 30 | 31 | componentWillMount() { 32 | // AsyncStorage.removeItem('@FeedList'); 33 | LocalStorage.bootstrap(() => this.setState({bootstrapped: true})); 34 | } 35 | 36 | render() { 37 | if (this.state.bootstrapped == false) { 38 | return ; 39 | } 40 | return ( 41 | { 50 | this.refs.mainNav.navigator.push({ 51 | component: NewFeed, 52 | title: 'New Feed', 53 | }); 54 | } 55 | }} 56 | tintColor="#FFFFFF" 57 | barTintColor="#183E63" 58 | titleTextColor="#FFFFFF"/> 59 | ); 60 | } 61 | }; 62 | 63 | var styles = StyleSheet.create({ 64 | container: { 65 | flex: 1 66 | } 67 | }); 68 | 69 | AppRegistry.registerComponent('RssReader', () => RssReader); 70 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RssReader", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "start": "node_modules/react-native/packager/packager.sh" 7 | }, 8 | "dependencies": { 9 | "flux-util": "^0.1.1", 10 | "lodash": "^3.8.0", 11 | "react-native": "^0.5.0" 12 | } 13 | } 14 | --------------------------------------------------------------------------------