Позиционирование мобильного веб-просмотра — опыт лазанья по ямам

Байду внешний интерфейс WeChat JavaScript

написать впереди

Недавнее бизнес-требование требует получения географического местоположения пользователя после входа на страницу, а затем отображения соответствующего контента на основе географического местоположения.

Однако звучит как очень простое требование. . Если в вашей компанииlbsЕсли это сервис, и без учета адаптации, то это действительно очень и очень просто. представитьsdkИли получить доступ к фоновому интерфейсу, вы можете получить соответствующее географическое положение. Конечно, есть полныеlbsЕсть только несколько компаний, которые обслуживают ссылку.

Другой - адаптация. Адаптация службы определения местоположения - это не адаптация модели, а адаптация платформы. Услуги, предоставляемые разными платформами, также непоследовательны. Давайте поговорим о нескольких методах позиционирования, их преимуществах и недостатках и организуем 1. Универсальное решение (возможно, универсального решения не существует).

lbs

Скажи это первымlbs, Не говоря уже о таком количестве бесполезных сервисов, основанных на местоположении, прислушиваясь к названию, каждый должен знать, что это такое.

Большинство зрелых интернет-платформ используют более или менееlbs, чтобы рекомендовать или искать на основе текущего географического местоположения пользователя.

Я говорю это, чтобы проиллюстрироватьlbsОчень часто используется, но это также аббревиатура, которую необходимо понимать.

location

окружающая обстановка

Во-первых, давайте поговорим о платформе, к которой должен адаптироваться наш бизнес:

  1. Внутри станции, то есть внутри приложения команды;
  2. WeChat, крупнейшая платформа для обмена данными за пределами сайта;
  3. Другие платформы за пределами мобильного терминала, включая, помимо прочего, QQ, Weibo, различные браузеры;
  4. Некоторые пользователи могут даже открывать WeChat на компьютере.

Окружающая среда плохая, не так ли? Если у вашей команды есть собственное приложение, и вы хотите, чтобы его контент был доступен и просматривался за пределами сайта, вам в основном необходимо учитывать четыре вышеуказанных пункта.

Если вы работаете над апплетом WeChat, то поздравляю, вам в принципе не нужно читать нижеследующее, потому что WeChat предоставил апплету хорошую среду разработки, и вам не нужно учитывать столько всего.

метод

Мобильное GPS-позиционирование

Этот метод мобильного GPS-позиционирования ограничен вашим собственным приложением. Как интерфейсная разработка, вам обычно не нужно пониматьnativeкак дать вам все видыJSBridgeиз. Но полезно немного знать.

Говоря оnativeа такжеwebСвязь, я должен сказать, JSBridge,nativeJSBridge предоставляет различные методы, которые необходимы, но недоступны для Интернета, такие как собственное позиционирование, использование микрофонов, камер и других устройств.

举个栗子

function setupWebViewJavascriptBridge(callback) {
    if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
    if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
    window.WVJBCallbacks = [callback];
    var WVJBIframe = document.createElement('iframe');
    WVJBIframe.style.display = 'none';
    WVJBIframe.src = 'https://__bridge_loaded__';
    document.documentElement.appendChild(WVJBIframe);
    setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
}
setupWebViewJavascriptBridge(function(bridge) {
    /* Initialize your app here */
    var button = document.querySelector(".JSToNativeButton");
    button.addEventListener('click', function(event) {
        bridge.callHandler('JsToNative', "This is a message from javascript to native");
    })
    bridge.registerHandler('NativeToJs', function(data, responseCallback) {
        alert(data);
    })
    // bridge.callHandler('ObjC Echo', {'key':'value'}, function responseCallback(responseData) {
    //     console.log("JS received response:", responseData)
    // })
})

Это очень простой веб-пример и нативный пример. Выше приведен код на стороне веб-сайта. Видно, что метод связи — это механизм мониторинга событий, который мы используем чаще всего. Вышеприведенный код выглядит немного запутанным, но он должен быть понятным, поэтому я не буду его много объяснять. Потому что это кажется немного не по теме. Теперь, когда мы не по теме, давай просто закончим, Орз. Ниже приведен соответствующий фрагмент кода OC.

[self.bridge registerHandler:@"JsToNative" handler:^(id data, WVJBResponseCallback responseCallback) {
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"message from JS" message:data preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *actionCancel = [UIAlertAction actionWithTitle:@"close" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        
    }];
    [alertController addAction:actionCancel];
    [self presentViewController:alertController animated:YES completion:nil];
}];

Короче говоря, JSBridge может реализовать связь на обоих концах, а нативный может зарегистрироватьwindowВышеупомянутый объект, который предоставляется веб-методу для регистрации событий (в приведенном выше кодеbridge.registerHandler), это событие регистрации может быть инициировано в нативе, и параметры передаются, чтобы натив мог уведомить веб-сторону. Событие можно зарегистрировать в нативной функции, а затем функцию события можно вызвать в сети, передав параметры, чтобы сеть могла вызвать нативную функцию.

Не по теме заходит достаточно далеко, но причина не по теме в том, что в плане действительно нечего сказать. Native соглашается с протоколом для вас, а затем вы вызываете этот протокол, передаете функцию и ждете обратного вызова. . В принципе, для нашего фронтенда нет больших сложностей и нагрузки.

Какой? Ваш родной не предоставляет этот протокол? Следующая итерация полна ими.

提需求的来啦

Хорош ли этот метод?

Конечно хорошо, очень хорошо. Расположение точна, подсказки дружелюбны, за исключением того, что разрешение появится (конечно, это также необходимо), он в основном является оптимальным решением в приложении. Конечно, если у вас есть большое количество данных позиционирования пользователей, и вы можете убедиться, что данные эффективны в режиме реального времени, то я не сказал это. Даже если есть интерфейс, будь то бесшумное позиционирование, пробуждает отвращение пользователей, по-прежнему требуется ваше взаимодействие и планирование для определения.

Эта небольшая демонстрация находится вНа моем гитхабе есть проекты, Ого, только что узнал, что пишу статью уже пол года, а гитхаб давно не обновлялся. .

Позиционирование H5

Новый стандарт дает нам массу возможностей для унификации калибра. Я должен сказать, что совместимость позиционирования H5 по-прежнему хороша.В настоящее время совместимость мобильных терминалов нашей команды поддерживает Android 4.4.2 и выше, а мобильные телефоны выше этой версии в основном поддерживают функцию позиционирования H5. Как раз когда я собирался использовать это в качестве первого решения, я обнаружил проблему, которая может свести взаимодействие с ума.

Во-первых, для позиционирования H5 потребуется сторонняя платформа, то есть разрешение приложения на географическое местоположение.

Пока одно из этих двух разрешений отменено, позиционирование H5 можно определить только по IP.

Два маркера не имеют значения. Самое главное - это позиционирование H5. Маркер в веб-просмотре будет отображать:www.xxx.com хочет получить информацию о вашем географическом местоположении., это сильно запутает пользователей, пользователи могут не знать ваше доменное имя, а знать только, как называется ваше программное обеспечение.

Помимо этих двух проблем, позиционирование H5 — очень хороший выбор для совместимости и единства внешнего позиционирования.

const noop = () => {};
getH5Location(options = {}) {
    const cb = options.cb || noop;
    const errCb = options.errCb || noop;
    let isLocation = false;
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(
            res => {
                isLocation = true;
                cb(res.coords.longitude, res.coords.latitude);
            },
            () => {
                isLocation = true;
                errCb();
            }
        );
    }
    // 定位兜底
    setTimeout(() => {
        if (!isLocation) {
            errCb();
        }
    }, 5000);
},

Это простой пакет позиционирования H5.Чтобы некоторые устройства не поддерживали позиционирование H5, был добавлен восходящий метод. Задержку нижнего триггера можно установить самостоятельно в соответствии с вашими потребностями.


Здесь следует обратить внимание на небольшую яму в позиционировании H5, которая заставила меня долго лазить. Как мы все знаем, H5 позиционируется в относительно новых браузерах и потребуетhttpsПротокол можно позиционировать только при переключении протокола наhttpsПосле этого вы найдете всеhttpВсе ресурсы блокируются позиционированием H5. Но если вы закомментируете код для позиционирования H5, вы обнаружитеhttpРесурс будет отображать только предупреждение, но может отображаться и в обычном режиме.

Если ваши статические ресурсы имеютhttpsверсия, рекомендуется использовать//via.placeholder.com/333x333Этот непротокольный метод введен для того, чтобы протоколы ресурсов можно было автоматически переключать, чтобы предотвратить блокировку ресурсов.


WeChat API

На платформе WeChat из-за различных мелких проблем с позиционированием H5, хотя это и не влияет на использование, эффект всегда немного хуже. Если ваша команда может подать заявку на WeChat SDK, это отлично.

Простой вызов, при условии, что вы внедрили js-sdk WeChat, это не очень сложная вещь. Документы, предоставленные WeChat, уже очень подробные, поэтому я не буду здесь вдаваться в подробности.

wx.getLocation({
    type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
    success: function (res) {
        var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
        var longitude = res.longitude ; // 经度,浮点数,范围为180 ~ -180。
        var speed = res.speed; // 速度,以米/每秒计
        var accuracy = res.accuracy; // 位置精度
    }
});

На платформе WeChat использование интерфейса WeChat, несомненно, является лучшим выбором. Он совершенен, прост и используется бесчисленным количеством людей.Это очень ХОРОШО, и платформа WeChat — это платформа, к которой вы должны адаптироваться, потому что платформа WeChat — это первая целевая точка для большинства ваших целевых страниц.

инструкцииДокументация общедоступной платформы WeChatЭто было написано очень подробно.

爸爸

Сторонний SDK (карта Baidu, карта AutoNavi и т. д.)

Это самый ненадежный метод, я целый день знакомился с Baidu Maps, AutoNavi Maps и Tencent Maps и пробовал их. Существует довольно своеобразный стиль обращения к врачу в спешке.

Тогда я задумался об этом основательно. По какому принципу они расположены. Разве они не определяют местонахождение по IP без разрешения GPS? ?

Конечно, после многих попыток я обнаружил, что некоторые из этих сторонних SDK будут расположены через H5, потому что всплывающее окноapi.map.xxx.com想要获取您的位置, так почему бы мне не использовать позиционирование H5. Закулисные отцы уже предоставили интерфейс для IP-позиционирования.Если IP-позиционирование все еще осуществляется через сторонний SDK, это не пустая трата тяжелой работы закулисных отцов.

Сторонние карты хороши, но их сервисы позиционирования не обязательно хороши.Если вам нужно только позиционирование, то не рассматривайте этот метод.Потому что основная функция стороннего картографического SDK — получить наглядную карту.

Я на самом деле потратил полдня, пытаясь понять эту проблему. .

Если вам нужен визуальный картографический сервис, выберите сторонний картографический SDK. Если это только для позиционирования, другие методы лучше, чем этот метод.

IP-позиционирование

Опираясь на интерфейс, предоставленный внутренним отцом, вы можете напрямую получать информацию о местоположении, хранящуюся во внутренней базе данных, через интерфейс. Или получить географическое положение через IP-адрес пользователя.

Смотрится красиво. Если вы ищете более точное позиционирование, то откажитесь от этого метода. IP-позиционирование очень плохо работает в сетях 4G.

В сетевой среде 4G IP-позиционирование обычно основывается на домашнем местоположении оператора или базовой станции. Если вы живете на Четвертом транспортном кольце в Пекине, скорее всего, вы находитесь в Шицзячжуане. .

Но нет никакого способа, в случае привилегии, IP-позиционирование может быть использовано в качестве плана или более реалистичного.

Окончательное решение

Ха-ха, на самом деле, так называемое окончательное решение состоит в том, чтобы адаптировать вышеуказанные решения.

  • Прежде всего, позвольте разработчикам клиента создать для вас JSBridge внутри приложения, чтобы вы могли правильно вызывать нативный метод позиционирования.

  • Во-вторых, WeChat, как первая платформа для обмена, конечно же, нуждается в особом уходе, WeChat позиционируется через js-sdk WeChat.

  • Опять же, для всех остальных мобильных и клиентских платформ его можно обобщить. Все используют позиционирование H5, жестокое и простое в использовании.

  • Наконец, после сбоя любого из позиционирования просто следуйте позиционированию IP.

Конечно, упомянутая выше такая сложная схема адаптации предназначена для того, чтобы вы могли получить лучший пользовательский опыт и дизайн. Если вы обнаружите проблемы или определенные условия не позволяют (срок действия клиентской строки истек? Не существует). В соответствии с вышеперечисленными преимуществами и недостатками, которые необходимо заменить, для их собственной программы это лучшая программа.

Наконец, не забудьте инкапсулировать свою функцию позиционирования, чтобы люди, стоящие за ней, могли легко использовать ее повторно. Вы определенно не захотите вернуться к этой сухой статье, когда вам понадобится позиционирование в следующий раз~

export const getLocation = (options = {
    cb: () => {},
    errCb: () => {},
}) => {
    const isInApp = Utils.getEnv().isInApp();
    const isInWechat = Utils.isInWechat();
    if (isInApp) {
        // 站内定位
        return this.getAppLocation(options);
    }
    if (isInWechat) {
        // 微信定位
        return this.getWechatLocation(options);
    }
    // H5定位
    return this.getH5Location(options);
},