2017-10-20 14:23:13 nucleus_ripples 阅读数 463

最近刚学Swift,总想着搞个大事件,可是实力不行,大事件还是不要搞了。利用百度地图简单写个小Demo吧。这样还能巩固Swift语法上的一些概念。百度SDK的下载,注册这里就不做介绍了。这里只写出自己如何思考以及如何利用百度地图SDK提供的API来实现自己的功能。

  • 概述
  • 利用地图SDK提供的定位服务,实现自己的功能。
  • 总结

概述

其实,市场上有几款很成熟的地图SDK供我们选择,对于大部分人来说,这些成熟的地图SDK提供的功能,都能满足我们的需求,问题在于,有时候很纠结啊!到底选择那个地图好呢?与其纠结那个地图好,倒不如想想,自己的APP需求是什么。这样自己封装出一些类供APP调用,而支撑这些类的功能代码,可以随意选择一个SDK。这样后期如果想更换SDK,其实很简单的事情,只需要在自己封装的类里改动就行了。调用封装类的代码无须改动。

利用地图SDK提供的定位服务,实现自己的功能

第一个类,获取坐标地址。需实现两个类,功能类和模型类。

  1. 功能类,提供坐标。
  2. 模型类,封装坐标信息、以及坐标所在的地址。之所以不用第三方提供的类型,是因为第三方不可能遵循一个标准。自己封装一个数据模型类。
//这里采用Objective-C实现功能类。
#import <Foundation/Foundation.h>
#import <BaiduMapAPI_Location/BMKLocationComponent.h>

/**
 * 设置locationAttributes属性,具体含义可参考CLLocationManager相关属性的注释。
 */
typedef NSString* AGLocationAttributedStringKey;
UIKIT_EXTERN AGLocationAttributedStringKey const AGDistanceFilterAttributeName;                         //CLLocationDistance
UIKIT_EXTERN AGLocationAttributedStringKey const AGDesiredAccuracyAttributeName;                        //CLLocationAccuracy
UIKIT_EXTERN AGLocationAttributedStringKey const AGHeadingFilterAttributeName;                          //CLLocationDegrees
UIKIT_EXTERN AGLocationAttributedStringKey const AGPausesLocationUpdatesAutomaticallyAttributeName;     //BOOL
UIKIT_EXTERN AGLocationAttributedStringKey const AGAllowsBackgroundLocationUpdatesAttributeName;        //BOOL


@class AGUserLocation;

typedef void(^UserLocation)(AGUserLocation *userLocation);

@interface AGLocation : NSObject

@property (nonatomic, strong) NSDictionary<AGLocationAttributedStringKey, id> *locationAttributes; //定位参数,定位根据参数,进行何时更新

@property (nonatomic, copy) UserLocation userlocation; //回调方法

- (void)startLocation; //开始定位
- (void)stopLocation; //停止定位

@end

// 数据模型类

#import <Foundation/Foundation.h>

@class CLLocation;
@interface AGUserLocation : NSObject

// 位置信息,尚未定位成功,则该值为nil
@property (nonatomic, strong) CLLocation *location;
// 定位标注点要显示的标题信息
@property (nonatomic, strong) NSString *title;
/// 其它信息
@property (nonatomic, strong) NSString *other;

@end

这里简单的给出了AGLocation、AGUserLocation的头文件,如果想看实现文件查看https://gitee.com/ag_explore/MapForSwift

简单的给出了AGLocation,项目中如果需要坐标的话,只需要创建AGLocation对象即可。AGLocation的功能可以是第三方SDK提供。也可以是iOS API提供。总之,上层调用者不关心AGLocation的实现。这应该是开发AGLocation的猿应该关心的事情。

下面给出调用方法

//这里使用的是Swift
        _location = AGLocation()
        _location?.locationAttributes = [AGDistanceFilterAttributeName:kCLLocationAccuracyBest]
        _location?.userlocation = { (userLocation:AGUserLocation?) -> Void in

            if let userLocation = userLocation {

                print("定位成功")
                print(userLocation.location)

            } else {

                print("定位失败")
            }

        }

        _location?.start() //开启定位

总结

使用AGLocation不关心AGLocation是这么实现的,它只需要关心AGLocation提供的功能是否满足。而AGLocation的实现,则需要实现AGLocation的程序员关心。这样做的好处是,我后期可以替换任何SDK。

这篇只是定位服务,下篇封装地图。

2018-06-07 10:22:35 baidu_33735542 阅读数 299

最近在写百度地图电子围栏加载,研究源码,也花了一些时间。

1、百度电子围栏整体思路

    1)用户创造实体,赋予监控权限

    2)对该实体创造电子围栏,有服务端和本地端两种方式,先创造实体,上传到的服务器中。在对实体创造电子围栏,服务器端的有多边形,圆形,本地端的只有圆形围栏。

    3)查询对于该实体的电子围栏操作,从代理返回值中在地图上画出围栏。

    4)检测实体运动轨迹,若超出范围,则报警。(创建实体,允许获得用户轨迹,百度后台返回的代理)

一、工程配置

    按照官网提示的即可,swift要加桥接而已。

二、

0、调用百度地图服务之前,都需要设置ak mcode信息,否则调用不到

let sop: BTKServiceOption = BTKServiceOption(ak: "ksqN5xi5s2Kpc6jlqW6Km5zk524pDhmy", mcode: "www.arvin.com.baiduMap", serviceID: 200447, keepAlive: false)
        BTKAction.sharedInstance().initInfo(sop) 

ak 是在百度地图申请的,mcode是工程的Bundle id。

1、添加百度地图,因为我们用鹰眼围栏是需要在地图上画出图形来的。

 _mapView = BMKMapView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height))

        self.view.addSubview(_mapView!)

按照百度地图官网或者其demo即可。

2、添加百度地图的第一步是首先需要创建实体,并给实体创建电子围栏,上传给百度地图服务器

    //设置地理围栏
    func creatMapFrence() {
        //创建entity实体 entityDesc 字母数字下划线
        let request: BTKAddEntityRequest = BTKAddEntityRequest(entityName: "entityA", entityDesc: "ThissaentityA", columnKey: nil, serviceID: 00000, tag: 1)
        BTKEntityAction.sharedInstance().addEntity(with: request, delegate: self)
         //创建一个名称为“server_circle_fence” 的服务端圆形地理围栏,圆心坐标为东经116.3134度、北纬40.0478度,围栏半径为50米。它的监控对象为“entityA”,且当entityA这个终端实体的定位精度大于50米的轨迹点不参与此围栏的计算。
        //圆心40.055573298959558)Optional(116.30384089417596
        let center: CLLocationCoordinate2D = CLLocationCoordinate2D.init(latitude: 40.055573298959558, longitude: 116.30384089417596)
        //构造将要创建的新的围栏对象
        let fence: BTKServerCircleFence = BTKServerCircleFence(center: center, radius: 450.0, coordType: .COORDTYPE_BD09LL, denoiseAccuracy: 50, fenceName: "firstFenceName", monitoredObject: "entityA")
        //构建请求对象
        let circleRequest: BTKCreateServerFenceRequest = BTKCreateServerFenceRequest.init(serverCircleFence: fence, serviceID: 00000, tag: 1)
        //发起请求
        BTKFenceAction.sharedInstance().createServerFence(with: circleRequest, delegate: self)
      
    }

完成之后,我们需要调用创建实体是否成功的代理,判断是否创建成功

 //创建地理围栏返回代理
    func onCreateServerFence(_ response: Data!) {
        guard let array:[String: Any] = try! JSONSerialization.jsonObject(with: response, options: []) as? [String: Any] else {//转化失败就返回
            return
        }
        print("创建地理围栏\(array)")
    }

2、搜索我们可以在鹰眼代理BTKFenceDelegate 中查询我们所创建的实体

//查询围栏
    func qureyMapFernce() {
        //构建请求对象
        let request = BTKQueryServerFenceRequest(monitoredObject: "entityA", fenceIDs: nil, outputCoordType: .COORDTYPE_BD09LL, serviceID: 000000, tag: 1)
        //发送查询请求
        BTKFenceAction.sharedInstance().queryServerFence(with: request, delegate: self)
        
    }

查询地理围栏并且在地图上画出地理围栏

    func onQueryServerFence(_ response: Data!) {
        guard let array:[String: Any] = try! JSONSerialization.jsonObject(with: response, options: []) as? [String: Any] else {//转化失败就返回
            return
        }
        print("查询地理围栏\(array)")
        let size: NSInteger = array["size"] as! NSInteger
        //在地图上展示这些围栏
        //获取size 在地理位置信息
        //使用Annotation代表圆形围栏的圆心
        let centerAnnotations: NSMutableArray = NSMutableArray(capacity: size)
        //使用填充圆行围栏的覆盖物
        let radiusOverlays: NSMutableArray = NSMutableArray(capacity: size)
        //存储所有围栏的圆心位置,是为了确定地图的显示范围
        let coordinates: NSMutableArray = NSMutableArray(capacity: size)
        let dicFence: [[String: Any]] = array["fences"] as! [[String : Any]]
        
        for fence in dicFence {
            //筛选circle的圆
            let circle: String = fence["shape"] as! String
            if circle == "circle" {
                //解析数据 经纬度
                let fenceCenter: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: fence["latitude"] as! CLLocationDegrees, longitude: fence["longitude"] as! CLLocationDegrees)
                
                let fenceRadius: Double = fence["radius"] as! Double
                let fenceName: String = fence["fence_name"] as! String
                let denoiseAccuracy: NSInteger = fence["denoise"] as! NSInteger
                let monitoredObject: String = fence["monitored_person"] as! String
                
                //存贮圆心位置 /*略有问题*/
//                let coordinateValue: NSValue = NSValue.init(bytes: &fenceCenter, objCType: "CLLocationCoordinate2D")
                
                coordinates.add(fenceCenter)
                
                //构造Annotaion
                let annotation: BMKPointAnnotation = BMKPointAnnotation()
                annotation.coordinate = fenceCenter
                annotation.title = "预设名称\(fenceName)"
                annotation.subtitle = "半径:\(fenceRadius),去噪精度 \(denoiseAccuracy)"
                centerAnnotations.add(annotation)  //圆心数组
                
                //围栏的覆盖范围
                let coverageArea: BMKCircle = BMKCircle()
                coverageArea.coordinate = fenceCenter
                coverageArea.radius = fenceRadius
                
                radiusOverlays.add(coverageArea)
                
                
//                let annoationKey: NSValue = NSValue.value(annotation, withObjCType: <#UnsafePointer<Int8>#>)
                let annoationKey: NSValue = NSValue.init(nonretainedObject: annotation)  //转换NSDate
                
                //存储标注到围栏的映射
                let fenceObject: BTKServerCircleFence = BTKServerCircleFence(center: fenceCenter, radius: fenceRadius, coordType: .COORDTYPE_BD09LL, denoiseAccuracy: UInt(denoiseAccuracy), fenceName: fenceName, monitoredObject: monitoredObject)
                annotationMapToFenceObject.setObject(fenceObject, forKey: annoationKey)
                
                //存储标注到围栏ID的映射
                let fenceID: NSNumber = fence["fence_id"] as! NSNumber
                annotationMapToFenceID.setObject(fenceID, forKey: annoationKey)

            } else {
                
            }
        }
//        weak let weakSelf = self
        //在地图上展示围栏 //主队列 异步
        DispatchQueue.main.async {
            //清空原有的标注和覆盖物
            self._mapView?.removeOverlays(self._mapView?.overlays)
            self._mapView?.removeAnnotations(self._mapView?.annotations)
            //添加新的标注物和覆盖物
            self._mapView?.addAnnotations(centerAnnotations as! [Any])
            self._mapView?.addOverlays(radiusOverlays as! [Any])
            //设置地图的显示范围
            self.mapViewFitForCoordinates(points: coordinates)
        }
        
    }
//设置地图的显示范围
    func mapViewFitForCoordinates(points: NSArray) {
        var minLat: Double = 90.0
        var maxLat: Double = -90.0
        var minLon: Double = 180.0
        var maxLon: Double = -180.0
        for i in 0..<points.count {
            let coord: CLLocationCoordinate2D = points[i] as! CLLocationCoordinate2D
            minLat = fmin(minLat, coord.latitude)
            maxLat = fmax(maxLat, coord.latitude)
            minLon = fmin(minLon, coord.longitude)
            maxLon = fmax(maxLon, coord.longitude)
        }
        
        let center: CLLocationCoordinate2D = CLLocationCoordinate2DMake((minLat + maxLat) * 0.5, (minLon + maxLon) * 0.5)
        //设置经纬度范围
        let span = BMKCoordinateSpan(latitudeDelta: (maxLat - minLat) + 0.06, longitudeDelta: (maxLon - minLon) + 0.06)
        
        var region = BMKCoordinateRegion()
        region.center = center
        region.span = span
        
        self._mapView?.setRegion(region, animated: true)
    }
    
    
    //围栏的画图,需要实现这个代理,否则画不出来
    func mapView(_ mapView: BMKMapView!, viewFor overlay: BMKOverlay!) -> BMKOverlayView! {
        //判断是圆形
        if overlay is BMKCircle {
            let circleView = BMKCircleView.init(overlay: overlay)
            circleView?.fillColor = UIColor.init(red: 0, green: 0, blue: 1, alpha: 0.3)
            circleView?.strokeColor = UIColor.init(red: 0, green: 0, blue: 1, alpha: 0)
            return circleView
        } else {
            return nil
        }
        
        
        
    }

删除地理围栏

//删除围栏
    func deleteMapFrence() {
        //请求构造对象
        let request: BTKDeleteServerFenceRequest = BTKDeleteServerFenceRequest(monitoredObject: "entityA", fenceIDs: nil, serviceID: 200447, tag: 22)
        //发起删除请求
        BTKFenceAction.sharedInstance().deleteServerFence(with: request, delegate: self)
    }

删除地理围栏代理

 //删除围栏
    func onDeleteServerFence(_ response: Data!) {
        guard let array:[String: Any] = try! JSONSerialization.jsonObject(with: response, options: []) as? [String: Any] else {//转化失败就返回
            return
        }
        print("删除地理围栏\(array)")
    }

更新地理围栏

//更新围栏
    func updateMapFrence() {
        //新的圆心
        let center: CLLocationCoordinate2D = CLLocationCoordinate2DMake(40.1578, 116.2234)
        //新的圆形围栏
        let fence: BTKServerCircleFence = BTKServerCircleFence(center: center, radius: 60, coordType: .COORDTYPE_BD09LL, denoiseAccuracy: 60, fenceName: "server_fence_60", monitoredObject: "entityB")
        //构建请求对象
        let request: BTKUpdateServerFenceRequest = BTKUpdateServerFenceRequest(serverCircleFence: fence, fenceID: 138, serviceID: 200447, tag: 1)
        //发起更新请求
        BTKFenceAction.sharedInstance().updateServerFence(with: request, delegate: self)

    }

实时查询

    //实时状态查询
    func querServerFenceStatus() {
        //实时状态查询
        //鹰眼iOS SDK支持查询指定监控对象的状态,监控对象即某个终端实体(,,),监控对象是指其相对其上的地理围栏的位置关系,是在圆形或
        //多边形围栏的内部还是外部,是否偏离了线性围栏等。
        let request: BTKQueryServerFenceStatusRequest = BTKQueryServerFenceStatusRequest(monitoredObject: "entityA", fenceIDs: nil, serviceID: 200447, tag: 25)
        //发起查询请求
        BTKFenceAction.sharedInstance().queryServerFenceStatus(with: request, delegate: self)
        
//        以下代码片段表示,假设“entityA”这个终端实体在东经120.44度,北纬40.11度的话,该终端实体和其上的fenceID为17、23、29的这几个服务端地理围栏的位置关系,只有这几个地理围栏的监控对象是“entityA”这个终端实体时才有意义,如果不知道有哪些地理围栏在监控“entityA”这个终端实体,则fenceIDs属性传入nil即可。
        let customLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(40.11, 120.44)
        //地理围栏ID列表
//        NSArray *fenceIDs = ["",""]
        //构建请求对象
        let requestB: BTKQueryServerFenceStatusByCustomLocationRequest = BTKQueryServerFenceStatusByCustomLocationRequest(monitoredObject: "entityA", customLocation: customLocation, coordType: .COORDTYPE_BD09LL, fenceIDs: nil, serviceID: 200447, tag: 28)
        //发起查询请求
        BTKFenceAction.sharedInstance().queryServerFenceStatusByCustomLocation(with: requestB, delegate: self)
        
    }

若是获取报警信息,我们应用的是BTKTraceDelegate的代理

//报警推送
    //当服务器围栏被触发之后,会通过长链接将报警信息推送给SDK,SDK会通过BTKActionDelete SDK会通过 BTKActionDelegate 协议的 -(void)onGetPushMessage:(BTKPushMessage *)message; 方法将报警信息推送给开发者。因此服务端围栏的报警推送要求网络畅通。当接收报警的手机断网或网络状态不好时,会导致报警推送失败,鹰眼服务端将在后续的10分钟之内每隔15s推送一次,直至收到成功响应。若10分钟之后仍未成功,将不再推送,但报警记录将存储在鹰眼服务端。为避免因此造成报警漏接收,开发者可定期使用历史报警查询接口同步报警信息。
    /*BTKTraceDelegate*/ //需要定义实体检测其轨迹
    func onGet(_ message: BTKPushMessage!) {
        //获得推送消息
        if (message.type != 0x03 && message.type != 0x04) {
            return;
        }
        let content: BTKPushMessageFenceAlarmContent = message.content as! BTKPushMessageFenceAlarmContent
        var fenceName: String = "「" + content.fenceName + "」"
        let monitoredObject = "「" + content.monitoredObject + "」"
        var action = ""
        if content.actionType == .FENCE_MONITORED_OBJECT_ACTION_TYPE_ENTER {
            action = "进入"
        } else {
            action = "离开"
        }
        let fenceType = ""
        if message.type == 0x03 {
            fenceName = "服务器围栏"
        } else {
            fenceName = "客户端围栏"
        }
        
        //通过触发报警的轨迹点,解析出触发报警的时间
        let currentPoint: BTKFenceAlarmLocationPoint = content.currentPoint
        let dataFormatter: DateFormatter = DateFormatter()
        dataFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        let alarmDate: Date = Date(timeIntervalSince1970: TimeInterval(currentPoint.loctime))
        let alarmDateStr: String = dataFormatter.string(from: alarmDate)
        
        let puchMessage: String = "终端" + monitoredObject + "在" + alarmDateStr + action + fenceType + fenceName
        //
        print("推送消息\(puchMessage)")
        
        let deviceType: String = UIDevice.current.systemVersion
        let deviceTypeDouble: Double = Double(deviceType)!
        
        if deviceTypeDouble >= 10.0 {
            // 发送本地通知UNNotificationRequest
            let notificationContent: UNMutableNotificationContent = UNMutableNotificationContent()
            notificationContent.title = "报警" + fenceType
            notificationContent.body = puchMessage
            notificationContent.sound = UNNotificationSound.default()
            let notificationTrigger: UNTimeIntervalNotificationTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 0.1, repeats: false)
            let idd = "YYPushMessageNotificationIdentifier" + puchMessage
            
            let request: UNNotificationRequest = UNNotificationRequest(identifier: idd, content: notificationContent, trigger: notificationTrigger)
            UNUserNotificationCenter.current().add(request) { (error) in
                let errorMessage: NSError = error! as NSError
                if errorMessage.description == "" {
                    print("地理围栏报警发送失败" + error.debugDescription)
                } else {
                    print("消息发送成功")
                    UIApplication.shared.applicationIconBadgeNumber += 1
                }
            }
            
            
            
        } else {
            
            
        }
        
        
    }

希望能帮到你们。





2016-11-16 17:17:30 callzjy 阅读数 2627
//
//  ViewController.swift
//  baidumapfirsttest
//
//  Created by targetcloud on 2016/11/16.
//  Copyright © 2016年 targetcloud. All rights reserved.
import UIKit

class ViewController: UIViewController {

    var _mapView: BMKMapView?
    
    lazy var searcher: BMKPoiSearch = {
        let searcher = BMKPoiSearch()
        searcher.delegate = self
        return searcher
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        _mapView = BMKMapView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height))
        self.view.addSubview(_mapView!)
        //设置起始中心点
        let center = CLLocationCoordinate2D(latitude: 31.272881101147327, longitude: 121.61539365113157)
        _mapView?.centerCoordinate = center
        //设置区域
        let span = BMKCoordinateSpanMake(0.011929035022411938, 0.0078062748817018246)
        let region = BMKCoordinateRegionMake(center, span)
        _mapView?.setRegion(region, animated: true)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        _mapView?.viewWillAppear()
        searcher.delegate = self
        _mapView?.delegate = self // 此处记得不用的时候需要置nil,否则影响内存的释放
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        _mapView?.viewWillDisappear()
        searcher.delegate = nil
        _mapView?.delegate = nil // 不用时,置nil
    }
}

extension ViewController: BMKMapViewDelegate {
    func mapview(_ mapView: BMKMapView!, onLongClick coordinate: CLLocationCoordinate2D) {
        print(coordinate);//CLLocationCoordinate2D(latitude: 31.273070191233703, longitude: 121.61624006488663)
        // 调整区域 根据长按的位置
        let span = BMKCoordinateSpanMake(0.011929035022411938, 0.0078062748817018246)
        let region = BMKCoordinateRegionMake(coordinate, span)
        mapView.setRegion(region, animated: true)
        
        let option = BMKNearbySearchOption()
        option.pageIndex = 0
        option.pageCapacity = 20
        option.location = coordinate//根据长按的位置
        option.keyword = "小吃"
        let flag = searcher.poiSearchNear(by: option)
        if flag{
            print("周边检索发送成功")
        }else{
            print("周边检索发送失败")
        }
    }
    
    //点击大头针
    func mapView(_ mapView: BMKMapView!, annotationViewForBubble view: BMKAnnotationView!) {
        let annotaiton = view.annotation
        print(">>>\(annotaiton?.coordinate)\(annotaiton?.title!())\(annotaiton?.subtitle!())")//>>>Optional(__C.CLLocationCoordinate2D(latitude: 31.273627860569221, longitude: 121.61636597701556))Optional("美滋滋零食")Optional("上海市浦东新区")
    }
    
    //区域改变
    func mapView(_ mapView: BMKMapView!, regionDidChangeAnimated animated: Bool) {
        print(mapView.region.center,mapView.region.span)//CLLocationCoordinate2D(latitude: 31.272873385065104, longitude: 121.61537568502136) BMKCoordinateSpan(latitudeDelta: 0.011921347023825746, longitudeDelta: 0.0078062748817018246)
    }
}

extension ViewController: BMKPoiSearchDelegate {
    func onGetPoiResult(_ searcher: BMKPoiSearch!, result poiResult: BMKPoiResult!, errorCode: BMKSearchErrorCode) {
        if errorCode == BMK_SEARCH_NO_ERROR {
            print("周边检索成功")
            print(poiResult.poiInfoList)
            let poiInfos = poiResult.poiInfoList as! [BMKPoiInfo]
            for poiInfo in poiInfos {
                print(poiInfo.name, poiInfo.address)
                //加大头针
                let annotation = BMKPointAnnotation()
                annotation.coordinate = poiInfo.pt//CLLocationCoordinate2D
                annotation.title = poiInfo.name
                annotation.subtitle = poiInfo.address
                _mapView?.addAnnotation(annotation)
            }
        }else {
            print("周边检索失败")
        }
    }
}
/*
 周边检索发送成功
 周边检索成功
 [<BMKPoiInfo: 0x6000002b0e60>, <BMKPoiInfo: 0x6000002af3c0>, <BMKPoiInfo: 0x6000002b0200>, <BMKPoiInfo: 0x6000002b0e00>, <BMKPoiInfo: 0x6000002b1ee0>, <BMKPoiInfo: 0x6000002af300>, <BMKPoiInfo: 0x6000002a6d20>, <BMKPoiInfo: 0x6000002af060>, <BMKPoiInfo: 0x6000002b01a0>, <BMKPoiInfo: 0x6000002b1f40>, <BMKPoiInfo: 0x6000002b0da0>, <BMKPoiInfo: 0x6000002b3920>, <BMKPoiInfo: 0x6000002b0f20>, <BMKPoiInfo: 0x6000002a6e40>, <BMKPoiInfo: 0x6000002b3260>, <BMKPoiInfo: 0x6000002bd400>, <BMKPoiInfo: 0x6000002b3500>, <BMKPoiInfo: 0x6000002b3320>, <BMKPoiInfo: 0x6000002b3380>, <BMKPoiInfo: 0x6000002b3980>]
 绝味鸭脖(佳林路二店) 佳林路161号底层
 2016-11-16 17:11:35.399825 baidumapfirsttest[6234:238428] [Graphics] UIColor created with component values far outside the expected range. Set a breakpoint on UIColorBreakForOutOfRangeColorComponents to debug. This message will only be logged once.
 林家面馆 佳林路147号(近金高路)
 上海面馆 金高路2072号(东陆路口)
 和府私房牛肉面 佳林路88号
 渝客麻辣烫(金高路店) 金高路1736号(廊亦舫对面)
 东北味小吃 佳林路125号
 百年龙袍蟹黄汤包(金桥店) 金高路1757号金桥佳邻坊1F
 巴比馒头(东陆路) 浦东新区东陆公路与金高路交叉口旁
 李记红烧牛肉面麻辣烫 金高路2066号
 正宗潮汕砂锅粥 金高路1897号
 金桥汇 金高路1777号金桥文体中心4楼
 来伊份(NO.3521店) 东陆公路1980号
 沙县小吃 金高路1788号
 精品黄焖鸡米饭 金高路2068号(东陆路)
 蒸味坊馒头 上海市浦东新区金高路1764号
 重庆鸡公煲巫山烤全鱼 佳林路137号
 银记桂林米粉 上海市浦东新区
 塞北风 金高路2088号
 美滋滋零食 上海市浦东新区
 沙县小吃 上海市浦东新区
 */

2016-11-16 02:30:54 callzjy 阅读数 1600

ViewController.swift

//
//  ViewController.swift
//  baidumapfirsttest
//
//  Created by targetcloud on 2016/11/16.
//  Copyright © 2016年 targetcloud. All rights reserved.

//准备:
//下载包
//http://wiki.lbsyun.baidu.com/cms/iossdk/sdk/BaiduMap_IOSSDK_v3.1.0_All.zip
//生成密钥(API控制台) http://lbsyun.baidu.com/apiconsole/key
//wRRSuxGeEiD1yiPv8ej4XucCnTbjtQfR

//开始集成
//1 add ATS

//2 拖包
//BaiduMapAPI_Base.framework
//BaiduMapAPI_Cloud.framework
//BaiduMapAPI_Location.framework
//BaiduMapAPI_Map.framework
//BaiduMapAPI_Radar.framework
//BaiduMapAPI_Search.framework
//BaiduMapAPI_Utils.framework

//3 添加系统库的依赖在Linked Frameworks and Libraries
//CoreLocation.framework
//QuartzCore.framework
//OpenGLES.framework
//SystemConfiguration.framework
//CoreGraphics.framework
//Security.framework
//libsqlite3.0.tbd
//CoreTelephony.framework
//libstdc++.6.0.9.tbd

//4 在Build Settings 查找框中输入other link,然后在找到下面列表中的 Other Linker Flags 中输入-ObjC

//5 拖入BaiduMapAPI_Map.framework-> Resources-> mapapi.bundle 到工程中

//6 创建桥接文件(OC 到 swift), 在BMKSwiftDemo-Bridging-Header.h中输入
//#import <BaiduMapAPI_Base/BMKBaseComponent.h>//引入base相关所有的头文件
//#import <BaiduMapAPI_Map/BMKMapComponent.h>//引入地图功能所有的头文件
//#import <BaiduMapAPI_Search/BMKSearchComponent.h>//引入检索功能所有的头文件
//#import <BaiduMapAPI_Cloud/BMKCloudSearchComponent.h>//引入云检索功能所有的头文件
//#import <BaiduMapAPI_Location/BMKLocationComponent.h>//引入定位功能所有的头文件
//#import <BaiduMapAPI_Utils/BMKUtilsComponent.h>//引入计算工具所有的头文件
//#import <BaiduMapAPI_Radar/BMKRadarComponent.h>//引入周边雷达功能所有的头文件
//#import <BaiduMapAPI_Map/BMKMapView.h>//只引入所需的单个头文件

//7配置桥接文件
//在 Build Setting 查找框中输入brid,在下面的列表中找到Objective-C Bridging Header 中输入baidumapfirsttest/BMKSwiftDemo-Bridging-Header.h

//8 info.plist 添加Bundle display name

//9 添加代码

import UIKit

class ViewController: UIViewController {

    var _mapView: BMKMapView?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        _mapView = BMKMapView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height))
        self.view.addSubview(_mapView!)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        _mapView?.viewWillAppear()
//        _mapView?.delegate = self // 此处记得不用的时候需要置nil,否则影响内存的释放
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        _mapView?.viewWillDisappear()
        _mapView?.delegate = nil // 不用时,置nil
    }
}

AppDelegate.swift

//
//  AppDelegate.swift
//  baidumapfirsttest
//
//  Created by targetcloud on 2016/11/16.
//  Copyright © 2016年 targetcloud. All rights reserved.
//

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    var _mapManager: BMKMapManager?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        _mapManager = BMKMapManager()
        // 如果要关注网络及授权验证事件,请设定generalDelegate参数
        let ret = _mapManager?.start("wRRSuxGeEiD1yiPv8ej4XucCnTbjtQfR", generalDelegate: nil)
        if ret == false {
            NSLog("manager start failed!")
        }
        return true
    }

    func applicationWillResignActive(_ application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }

    func applicationWillTerminate(_ application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }


}


2019-11-30 22:55:09 qq_29077017 阅读数 13

在使用Swift语言,利用百度地图开放平台的iOS定位SDK进行开发时,可能会遇到一些小问题。基于一些笔者在开发过程遇到的问题,本文对问题进行了总结,并且给出了相应的解决方案供各位入门的开发者参考。

概述

笔者为iOS开发小白,近期尝试利用Swift语言,主要参考百度地图开放平台的iOS定位SDK开发文档进行定位功能的APP开发。开发指南主要是对Objective-C语言的开发方法进行的讲解,但是未对Swift语言开发进行细节描述。本文对开发初期遇到的自动部署和桥接文件问题进行了总结,查找资料获取其解决方案进行了记录,并对开发文档内容进行了补充。


自动部署

在进行自动部署过程中,完成创建Podfile的创建之后,根据开发文档,编辑Podfile内容如:

platform :ios, '7.0'
target 'mytestLocPodApp' do  #工程名字
  pod 'BMKLocationKit'
end

对于上述内容,有两个地方需要根据实际的情况进行修改。首先,将1行platform后的’7.0’改为目前创建应用的iOS平台版本,如最新的’13.2’。其次,将第2行target后的’mytestLocPodApp’更改为自己项目的饿名称,如’swiftLocTest’。按照这样描述的情况,得到的Podfile内容为:

platform :ios, '13.2'
target 'swiftLocTest' do  #工程名字
  pod 'BMKLocationKit'
end

此后再进行接下来的pop install操作。
直接在控制台执行pop install,出现了如下图所示的报错。
在这里插入图片描述
查找相关资料,发现其解决方案,即在控制台输入

pod repo remove trunk

然后重新执行

pod install 

即可成功实现自动部署,完成自动部署的正确结果如下图所示。
在这里插入图片描述


桥接文件配置

如果需要利用Swift通过百度地图定位iOS SDK进行开发,需要对桥接文件进行配置。
在完成上述自动部署之后,可以看到文件工程所在目录中出现了一个后缀名为.xcworkspace的文件。双击这一文件,以打开包含有SDK内容的完整工程。接下来,需要在工程中创建一个桥接文件。
在XCode的菜单栏中,打开File->New->File…,如下图所示。
在这里插入图片描述
然后,在弹出的对话框中,选择Header File,并将文件名拟为BMKSwiftDemo-Bridging-Header.h。创建位置选择到和上述.xcworkspace文件同一级别的目录,Group选择到最高级别,如下图所示。
在这里插入图片描述
完成桥接头文件的创建后,对文件填写如下内容:

#ifndef BMKSwiftDemo_Bridging_Header_h
#define BMKSwiftDemo_Bridging_Header_h

#import <BMKLocationKit/BMKLocationComponent.h>



#endif /* BMKSwiftDemo_Bridging_Header_h */

即引入了BMKLocationKit下的BMKLocationComponent.h头文件。因为这一文件已经包含定位所需的其他头文件,所以仅引入这一文件即可。
随后,需要对桥接文件进行配置。在Targets->Build Settings->Swift Compiler - General中,将Objective-C Bridging Header项的值更为BMKLocationComponent.h即可完成配置,如下图所示。
在这里插入图片描述
接下来,可以根据开发文档的后续描述进行开发~

没有更多推荐了,返回首页