Часть IV
Итак, теперь, когда я рассказал о том, что было связано с настройкой серверной части, я хочу немного больше поговорить о внешнем интерфейсе, о том, как я занимался получением местоположений и о том, как различные компоненты в приложении разговаривать друг с другом и делиться информацией о местоположении друг с другом.
Это не совсем ясно, но Xcode требует от вас некоторой настройки, чтобы включить определенные функции в вашем приложении. Возьмем, к примеру, «фоновые режимы». Для моего приложения мне нужно, чтобы ваш iPhone мог отслеживать ваше местоположение, и хотя у меня есть javascript:
getLocation = () => { navigator.geolocation.getCurrentPosition(currentPosition => { this.props.dispatchedNewCenter({latitude: currentPosition.coords.latitude, longitude:currentPosition.coords.longitude}), this.props.dispatchedCircleCenter({latitude: currentPosition.coords.latitude, longitude:currentPosition.coords.longitude}) }) }
iPhone не сможет продолжать отслеживать ваше местоположение без включенного фонового режима для служб определения местоположения, и даже в этом случае ваш конечный пользователь должен будет явно разрешать службы определения местоположения при открытии приложения.
Фоновые режимы находятся на вкладке возможностей в вашем проекте Xcode, и там вам нужно будет проверять обновления местоположения. Это также будет верно, если вы собираетесь использовать покупки в приложении, которые не находятся в фоновых режимах, но, тем не менее, это возможность отметить «возможности».
Я хочу воспользоваться моментом, чтобы отметить несколько вещей о приведенном выше коде; это довольно стандартный способ (насколько я могу судить) геолокации вашего пользователя, но:
а) это функция, которая вызывается и не «следит» за вашим местоположением
б) есть что-то происходит с props.dispatchedCircleCenter()
и т. д.
У HustleTime действительно есть 2 ключа в Redux, которые содержат информацию о местоположении. Есть центр круга, то есть место, которое находится в центре просматриваемой карты, и второе место, где на самом деле стоит пользователь. И это заставляет задать, может быть, 2 вопроса:
а) почему мы не отслеживаем местоположение при перемещении пользователя?
б) что такое Redux и каковы ключи в Redux?
Простой ответ на первый вопрос: да, мы отслеживаем местоположение пользователя. Но эта функция вызывается в другом месте просто потому, что приложению действительно все равно, где вы стоите, если вы сначала не откроете приложение или не переместите карту на свое местоположение. Чтобы отслеживать местоположение пользователя, я установил следующее в компоненте, который отображает маленькую иконку пользователя на карте, и это выглядит примерно так:
getUserLocation = () => { navigator.geolocation.getCurrentPosition(userPosition => { this.setState({ lat: userPosition.coords.latitude lng: userPosition.coords.longitude }) }) } componentDidMount(){ this.getUserLocation() } componentDidUpdate(){ this.watchID = navigator.geolocation.watchPosition( position => { this.setState({ lat:position.coords.latitude, lng:position.coords.longitude }) }) }
Для целей определения местоположения пользователя мы просто используем состояние, а не Redux (подробнее об этом чуть позже) просто потому, что нам действительно нужно отслеживать данные о местоположении только для рендеринга маленькой иконки на карте, и для этого мы повторное использование метода жизненного цикла componentDidUpdate(), доступного в React Native.
Вы можете сделать это с помощью Redux, который позволяет управлять состоянием нескольких компонентов. Вот чем props.dispatchedCircleCenter
был раньше. По сути, мы берем эту функцию из redux и сопоставляем ее с реквизитами, чтобы она была доступна в каждом компоненте, который мы хотим, чтобы она была доступна здесь. Вот пример того, как это выглядит в компоненте:
const mapStateToProps = (state) => { return { stations: state.stations, circleCenter: state.circleCenter } } const mapDispatchToProps = (dispatch) => { return { dispatchedFetchStations: (stations) => dispatch(fetchStations(stations)), dispatchedCircleCenter: (coords) => dispatch(setCircleCenter(coords)), dispatchedNewCenter: (coords) => dispatch(setNewCenter(coords)), dispatchedActiveMarker: (name) => dispatch(setActiveMarker(name)) } }
Здесь мы сопоставляем 2 ключа с состоянием и 4 функции с реквизитами. Теперь каждый из них будет доступен в этом конкретном компоненте в качестве реквизита.
Redux — особенно полезная библиотека, которую можно включить практически в любой проект React-Native, но она не ограничивается только React-Native. Он доступен для многих, многих фреймворков js. Я настоятельно рекомендую привыкнуть к работе с Redux, даже если это означает использование его в приложении, которому на самом деле не нужно передавать свойства от компонента к компоненту.
В следующем посте я немного расскажу о том, как мне удалось сохранить пользовательские данные на каждом отдельном устройстве, не отправляя эти данные в мою базу данных и не выполняя вызов API.