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

前言:
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í)目錄


圖片.png

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

圖片.png

3.pod update一下


圖片.png

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


圖片.png

最后發(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代碼


圖片.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);
                }
            );
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容