前言:
1.制作自定義插件,獲取地理位置信息,包括城市區(qū)域和街道名
2.oc寫原生代碼,暴露接口,提供給weex調(diào)用
開發(fā)環(huán)境:xcode10
開發(fā)平臺(tái):ios和weexeros
一.本地引入自己制作的pod
1.修改Podfile文件,增加 pod 'CJNativeCodeForWeexEros', :path=>'./CJNativeCodeForWeexEros/'
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
#忽略引入庫(kù)的警告
inhibit_all_warnings!
def common
#WeexSDK
pod 'WeexSDK', :git => 'https://github.com/bmfe/incubator-weex.git'
#Weex debugger 調(diào)試工具,只在開發(fā)模式集成
pod 'WXDevtool', :git => 'https://github.com/bmfe/weex-devtool-iOS.git', :configurations => ['Debug']
#Eros iOS 基礎(chǔ)庫(kù)
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
因?yàn)槭潜镜匾耄皇羌虞d遠(yuǎn)程倉(cāng)庫(kù)的,所以需要把代碼放到Podfile同級(jí)目錄

2.查看podspec文件,確保路徑正確
Pod::Spec.new do |s|
s.name = "CJNativeCodeForWeexEros" #插件名稱
s.version = "1.0.4" #版本號(hào)
s.summary = "Just Testing." #簡(jiǎn)短介紹,下面是詳細(xì)介紹
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" #主頁(yè),這里要填寫可以訪問(wèn)到的地址,不然驗(yàn)證不通過(guò)
s.license = 'MIT' #開源協(xié)議
s.author = { "appleJun" => "cj2527@163.com" } #作者信息
s.source = { :git => "https://github.com/cj2527/CJNativeCodeForWeexEros.git", :tag => s.version.to_s } #項(xiàng)目地址,這里不支持ssh的地址,驗(yàn)證不通過(guò),只支持HTTP和HTTPS,最好使用HTTPS
s.platform = :ios, '8.0' #支持的平臺(tái)及版本
s.requires_arc = true #是否使用ARC,如果指定具體文件,則具體的問(wèn)題使用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,多個(gè)用逗號(hào)隔開
end
注意s.resources = 'CJNativeCodeForWeexEros/'
s.source_files = "CJNativeCodeForWeexEros/.{h,m,mm}"
表示引入自己制作pod插件的CJNativeCodeForWeexEros目錄下及子目錄所有文件

3.pod update一下

二、原生代碼獲取具體地址信息,提供接口供weex調(diào)用
CJLocationManager.h代碼如下
//
// CJTLocationManager.h
// 修改JYTTLocationManager而來(lái),用來(lái)拓展獲取具體的地理位置信息
#import <Foundation/Foundation.h>
typedef void(^CurrentLocationBlock)(NSString *lon, NSString *lat,NSString *city,NSString *subLocality,NSString *street);
@interface CJLocationManager : NSObject
+ (instancetype)shareInstance;
/**
* 獲取當(dāng)前坐標(biāo)
*
* @param block 返回經(jīng)緯度
*/
- (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];
//設(shè)置代理
_locationManager.delegate = self;
//設(shè)置定位精度
_locationManager.desiredAccuracy=kCLLocationAccuracyBest;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
[_locationManager requestWhenInUseAuthorization];
}
}
return _locationManager;
}
- (void)updateCurrentLocation
{
if (![CLLocationManager locationServicesEnabled]) {
WXLogInfo(@"定位服務(wù)當(dāng)前可能尚未打開,請(qǐng)?jiān)O(shè)置打開!");
[self callBackWithLongitude:nil latitude:nil city:nil subLocality:nil street:nil];
return;
}
/* 如果沒有授權(quán)或者受限制返回nil */
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusRestricted || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied) {
[self callBackWithLongitude:nil latitude:nil city:nil subLocality:nil street:nil];
return;
}
//啟動(dòng)跟蹤定位
[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]; //取出第一個(gè)位置
/* 將gps坐標(biāo)系轉(zhuǎn)換成gcj-02坐標(biāo)系 */
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];
}
}];
}
/**
* 回調(diào)方法把經(jīng)緯度通過(guò)block回傳
*
* @param lng 經(jīng)度
* @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
{
// 判斷如果有緩存信息直接返回,無(wú)緩存則實(shí)時(shí)獲取一次
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文件遵守協(xié)議
#import <Foundation/Foundation.h>
#import "WeexSDK.h"
@interface CJTest : NSObject <WXModuleProtocol>
@end
.m文件實(shí)現(xiàn)
//
// 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};
}
/* 構(gòu)建callback數(shù)據(jù) */
NSDictionary *resultData = [NSDictionary configCallbackDataWithResCode:resCode msg:nil data:data];
callback(resultData);
}
}];
}
@end
3.注冊(cè)Modules

最后發(fā)現(xiàn)也是坑,一旦pod update,代碼也會(huì)重置,
所以還是自動(dòng)注冊(cè)的好
#import <WeexPluginLoader/WeexPluginLoader/WeexPluginLoader.h>
// 第一個(gè)參數(shù)為暴露給 js 端 Module 的名字,
// 第二個(gè)參數(shù)為你 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);
}
);