前言:
1.制作自定义插件,获取地理位置信息,包括城市区域和街道名
2.oc写原生代码,暴露接口,提供给weex调用
开发环境:xcode10
开发平台:ios和weexeros
一.本地引入自己制作的pod
1.修改Podfile文件,增加 pod 'CJNativeCodeForWeexEros', :path=>'./CJNativeCodeForWeexEros/'
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
#忽略引入库的警告
inhibit_all_warnings!
def common
#WeexSDK
pod 'WeexSDK', :git => 'https://github.com/bmfe/incubator-weex.git'
#Weex debugger 调试工具,只在开发模式集成
pod 'WXDevtool', :git => 'https://github.com/bmfe/weex-devtool-iOS.git', :configurations => ['Debug']
#Eros iOS 基础库
pod 'ErosPluginBaseLibrary', :git => 'https://github.com/bmfe/eros-plugin-ios-baseLibrary.git', :tag => '1.3.5'
#Other Plugins
pod 'CJNativeCodeForWeexEros', :path=>'./CJNativeCodeForWeexEros/'
end
target 'WeexEros' do
common
end
因为是本地引入,不是加载远程仓库的,所以需要把代码放到Podfile同级目录
2.查看podspec文件,确保路径正确
Pod::Spec.new do |s|
s.name = "CJNativeCodeForWeexEros" #插件名称
s.version = "1.0.4" #版本号
s.summary = "Just Testing." #简短介绍,下面是详细介绍
s.description = <<-DESC
Testing Private Podspec.
* Markdown format.
* Don't worry about the indent, we strip it!
DESC
s.homepage = "https://github.com/cj2527/CJNativeCodeForWeexEros" #主页,这里要填写可以访问到的地址,不然验证不通过
s.license = 'MIT' #开源协议
s.author = { "appleJun" => "cj2527@163.com" } #作者信息
s.source = { :git => "https://github.com/cj2527/CJNativeCodeForWeexEros.git", :tag => s.version.to_s } #项目地址,这里不支持ssh的地址,验证不通过,只支持HTTP和HTTPS,最好使用HTTPS
s.platform = :ios, '8.0' #支持的平台及版本
s.requires_arc = true #是否使用ARC,如果指定具体文件,则具体的问题使用ARC
s.source = { :git => 'https://github.com/cj2527/CJNativeCodeForWeexEros.git', :tag => s.version.to_s }
s.resources = 'CJNativeCodeForWeexEros/*'
s.source_files = "CJNativeCodeForWeexEros/*.{h,m,mm}"
s.frameworks = 'UIKit' #所需的framework,多个用逗号隔开
end
注意s.resources = 'CJNativeCodeForWeexEros/'
s.source_files = "CJNativeCodeForWeexEros/.{h,m,mm}"
表示引入自己制作pod插件的CJNativeCodeForWeexEros目录下及子目录所有文件
3.pod update一下
二、原生代码获取具体地址信息,提供接口供weex调用
CJLocationManager.h代码如下
//
// CJTLocationManager.h
// 修改JYTTLocationManager而来,用来拓展获取具体的地理位置信息
#import <Foundation/Foundation.h>
typedef void(^CurrentLocationBlock)(NSString *lon, NSString *lat,NSString *city,NSString *subLocality,NSString *street);
@interface CJLocationManager : NSObject
+ (instancetype)shareInstance;
/**
* 获取当前坐标
*
* @param block 返回经纬度
*/
- (void)getCurrentLocation:(CurrentLocationBlock)block;
/**
* 获取上一次定位信息
*
* @param block 返回上一次定位的信息
*/
- (void)getCacheLocation:(CurrentLocationBlock)block;
@end
CJLocationManager.m代码如下
//
// JYTLocationManager.m
// JingYitong
//
// Created by XHY on 16/5/26.
// Copyright © 2016年 XHY. All rights reserved.
//
#import "CJLocationManager.h"
#import <CoreLocation/CoreLocation.h>
#import "TransformCLLocation.h"
#import <UIKit/UIKit.h>
#import "WeexSDK.h"
@interface CJLocationManager () <CLLocationManagerDelegate>
{
CLLocationManager *_locationManager;
NSTimer *_timer;
}
@property (nonatomic, strong) CLLocationManager *locationManager;
@property (nonatomic, copy) CurrentLocationBlock currentLocationBlock;
@property (nonatomic, copy) NSString *cacheLng;
@property (nonatomic, copy) NSString *cacheLat;
@property (nonatomic, copy) NSString *cacheCity;
@property (nonatomic, copy) NSString *cacheSubLocality;
@property (nonatomic, copy) NSString *cacheStreet;
@end
@implementation CJLocationManager
+ (instancetype)shareInstance
{
static CJLocationManager *_instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (!_instance) {
_instance = [[CJLocationManager alloc] init];
}
});
return _instance;
}
- (CLLocationManager *)locationManager
{
if (!_locationManager) {
//定位管理器
_locationManager=[[CLLocationManager alloc]init];
//设置代理
_locationManager.delegate = self;
//设置定位精度
_locationManager.desiredAccuracy=kCLLocationAccuracyBest;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
[_locationManager requestWhenInUseAuthorization];
}
}
return _locationManager;
}
- (void)updateCurrentLocation
{
if (![CLLocationManager locationServicesEnabled]) {
WXLogInfo(@"定位服务当前可能尚未打开,请设置打开!");
[self callBackWithLongitude:nil latitude:nil city:nil subLocality:nil street:nil];
return;
}
/* 如果没有授权或者受限制返回nil */
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusRestricted || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied) {
[self callBackWithLongitude:nil latitude:nil city:nil subLocality:nil street:nil];
return;
}
//启动跟踪定位
[self.locationManager startUpdatingLocation];
}
- (void)timerAction
{
[self callBackWithLongitude:nil latitude:nil city:nil subLocality:nil street:nil];
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
CLLocation *location = [locations firstObject]; //取出第一个位置
/* 将gps坐标系转换成gcj-02坐标系 */
CLLocationCoordinate2D coordinate = [TransformCLLocation wgs84ToGcj02:location.coordinate];
[self.locationManager stopUpdatingLocation];
//反向地理编码
CLGeocoder *clGeoCoder = [[CLGeocoder alloc] init];
CLLocation *cl = [[CLLocation alloc] initWithLatitude:coordinate.latitude longitude:coordinate.longitude];
__block NSString *city=@"";
__block NSString *subLocality = @"";
__block NSString *street = @"";
[clGeoCoder reverseGeocodeLocation:cl completionHandler: ^(NSArray *placemarks,NSError *error) {
for (CLPlacemark *placeMark in placemarks) {
NSDictionary *addressDic = placeMark.addressDictionary;
NSString *state=[addressDic objectForKey:@"State"];
city=[addressDic objectForKey:@"City"];
subLocality=[addressDic objectForKey:@"SubLocality"];
street=[addressDic objectForKey:@"Street"];
NSLog(@"所在城市====%@ %@ %@ %@", state, city, subLocality, street);
[self callBackWithLongitude:[NSString stringWithFormat:@"%f",coordinate.longitude] latitude:[NSString stringWithFormat:@"%f",coordinate.latitude] city:city subLocality:subLocality street:street];
[self.locationManager stopUpdatingLocation];
}
}];
}
/**
* 回调方法把经纬度通过block回传
*
* @param lng 经度
* @param lat 纬度
*/
- (void)callBackWithLongitude:(NSString *)lng latitude:(NSString *)lat city:(NSString *)city subLocality:(NSString *)subLocality street:(NSString *)street
{
// 缓存位置信息
self.cacheLng = lng;
self.cacheLat = lat;
if (_timer) {
[_timer invalidate];
_timer = nil;
}
if (self.currentLocationBlock) {
self.currentLocationBlock(lng, lat,city,subLocality,street);
_currentLocationBlock = nil;
}
}
#pragma mark Public Method
- (void)getCurrentLocation:(CurrentLocationBlock)block
{
if (_timer) {
[_timer invalidate];
_timer = nil;
}
_timer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(timerAction) userInfo:nil repeats:NO];
self.currentLocationBlock = block;
[self updateCurrentLocation];
}
- (void)getCacheLocation:(CurrentLocationBlock)block
{
// 判断如果有缓存信息直接返回,无缓存则实时获取一次
if (self.cacheLng && self.cacheLng.length > 0 && self.cacheLat && self.cacheLat.length > 0) {
block(self.cacheLng,self.cacheLat,self.cacheCity,self.cacheSubLocality,self.cacheStreet);
} else {
[self getCurrentLocation:block];
}
}
@end
然后在CJTest.h文件遵守协议
#import <Foundation/Foundation.h>
#import "WeexSDK.h"
@interface CJTest : NSObject <WXModuleProtocol>
@end
.m文件实现
//
// CJTest.m
// CJNativeCodeForWeexEros
//
// Created by appleJun on 2019/3/15.
// Copyright © 2019 appleJun. All rights reserved.
//
#import "CJTest.h"
#import "CJLocationManager.h"
#import "NSDictionary+Util.h"
@implementation CJTest
@synthesize weexInstance;
WX_EXPORT_METHOD(@selector(getGeolocation:))
- (void)getGeolocation:(WXModuleCallback)callback
{
[[CJLocationManager shareInstance] getCurrentLocation:^(NSString *lon, NSString *lat,NSString *city,NSString *subLocality,NSString *street) {
if (callback) {
NSInteger resCode = BMResCodeError;
NSDictionary *data = nil;
if (lon && lat) {
resCode = BMResCodeSuccess;
data = @{@"locationLat": lat,@"locationLng": lon,@"city":city,@"subLocality":subLocality,@"street":street};
}
/* 构建callback数据 */
NSDictionary *resultData = [NSDictionary configCallbackDataWithResCode:resCode msg:nil data:data];
callback(resultData);
}
}];
}
@end
3.注册Modules
最后发现也是坑,一旦pod update,代码也会重置,
所以还是自动注册的好
#import <WeexPluginLoader/WeexPluginLoader/WeexPluginLoader.h>
// 第一个参数为暴露给 js 端 Module 的名字,
// 第二个参数为你 Module 的类名
WX_PlUGIN_EXPORT_MODULE(@"cjCommon", CJTest)
三、修改weex代码
1.src目录下增加cj.js文件,代码就模仿geo.js写
const cj = weex.requireModule('cjCommon')
const Cj = Object.create(null)
Cj.install = (Vue) => {
Vue.prototype.$cj = {
get () {
return new Promise((resolve, reject) => {
cj.getGeolocation(({ status, errorMsg, data }) => {
status === 0 ? resolve(data) : reject({ status, errorMsg, data })
})
})
}
}
}
Vue.use(Cj)
2.config目录下打开index.js文件
增加代码引入js
import '../widgets/src/cj'
3.就可以用this引用使用了
this.$cj.get().then(
data => {
this.selectedCity = data.city+data.street
console.log('city====',data.city)
},
error => {
this.$notice.toast({
message: '获取位置失败'
});
console.log(error);
}
);