5自定义地理位置pod插件201903

前言:
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同级目录


图片.png

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目录下及子目录所有文件

图片.png

3.pod update一下


图片.png

二、原生代码获取具体地址信息,提供接口供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


图片.png

最后发现也是坑,一旦pod update,代码也会重置,
所以还是自动注册的好

#import <WeexPluginLoader/WeexPluginLoader/WeexPluginLoader.h>
// 第一个参数为暴露给 js 端 Module 的名字,
// 第二个参数为你 Module 的类名
WX_PlUGIN_EXPORT_MODULE(@"cjCommon", CJTest)

三、修改weex代码


图片.png

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文件


图片.png

增加代码引入js
import '../widgets/src/cj'


图片.png

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);
                }
            );
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容