Using Baidu Maps SDK in Swift

Written in front
Baidu Maps SDK provides a set of powerful map framework interface, which not only provides the basic interface for building maps, but also provides services such as POI search, geocoding, route planning, positioning, and local overlay drawing. Since the instructions given on the official website of Baidu Maps SDK are developed using Objective-C language and Xcode 4, many friends have encountered many problems in the process of using Swift language for development. I wrote down my experience and shared it with you to help you quickly use Baidu Maps.
Baidu Maps update instructions
2.8.1
On July 16, Baidu Maps SDK released version 2.8.1 of the SDK, adding many new features.
In this version, Baidu Maps no longer provides SDK packages in the form of .a static libraries, but only provides SDK packages in the form of framework static libraries.
Additionally, support for iOS 9 has been added.
2.7.0
On April 9th, Baidu Maps SDK released the 2.7.0 version of the SDK, adding many new functions.
In this version, the most important change is to provide the SDK package of the framework static library, making the interaction between Baidu Maps SDK and Swift more friendly and convenient.
2.6.0
For children's shoes before iOS SDK 2.5.0, Baidu Map 2.6.0 has made the following updates. Please pay attention and don't be caught by these pitfalls.


Starting from 2.6.0, the user location update function has been changed from the original didUpdateUserLocation to didUpdateBMKUserLocation. This method needs to be modified to use the user location update of the location function.


Starting from 2.6.0, the user location update will be done by the BMKLocationService() class, so its startUserLocationService() method needs to be called to start the location operation.


Initial project configuration
After downloading the latest version of the SDK from the Baidu Maps SDK download page (download address, the latest version is 2.8.1) and applying for the key (application key tutorial), you can create a new project for the project The Baidu Map SDK is configured.
Copy files to the project
Use the .a static library of versions before 2.8.0
First, copy the header files (inc folder) and static library (.a) files provided by Baidu MapAPI to the project directory. Of course, if you want to save trouble, you can copy all the inc folder, static library files and mapapi.bundle package files to the project directory.
Here, I put all the static library files under the libs folder for easy management. As shown in the picture:  

project directory

Then don’t forget to drag these folders into the project, and check Copy if needed in the pop-up prompt.
Use the framework static library of version 2.7.0 or later
First, copy the framework (framework) file provided by Baidu MapAPI to the file directory. Here, we created a new Resource folder in the root directory of the project to store all the third-party frameworks needed in the project, and created a new BaiduMapSDK to store the SDK files.
Then don't forget to drag these folders into the project, and check Copy if needed in the pop-up prompt.
Bridging header file
Next, import the bridging header file (BaiduMapTest-Bridging-Header.h) into the project. There are many ways to add OC bridging header files, I will not introduce them in detail here:
The first method: Create a .mObjective-C file by yourself, and then XCode will prompt you whether to add a bridging header file. After selecting OK, the bridging header file will be created successfully, named "\(your project name)-Bridging- Header.h".

Add a bridging header file

The second method: add a .h file by yourself, and then add the path of this header file in Bulid Setting -> Swift Compiler - Code Generation -> Objective-C Bridging Header in the project settings.

OC bridging header file settings in Build Setting

Here I recommend you to use the first method, and I will explain the reason later.
After creation, enter the following statement under the bridging header file to introduce a reference to the Baidu API header file.
// framework framework header file import method, choose one of the following two methods
#import <BaiduMapAPI/BMapKit.h> // import all header files
#import <BaiduMapAPI/BMKMapView.h> // only import required header files
Configure static library compilation method
Change the .m file we created before to a .mm file. The specific operation method is to select the .m file, and then modify it in the file inspector in the function pane on the right side of the interface. First, change the .m file in the Name column to .mm, and then change the Type from Objective-C Source to Objective-C++ Source. As shown in the figure: Why do you want to do this

when modifying the .m file ?

Baidu already has a complete explanation:
Note: The static library is implemented in ObjectC++, so you need to ensure that you have at least one source file with the suffix .mm in your project (you can rename any file with the suffix .m to .mm), or specify the compilation method in the project properties , that is, set Xcode's Project -> Edit Active Target -> Build -> GCC4.2 - Language -> Compile Sources As to "Objective-C++"
but why don't we modify the compilation method? That's because we may also use other third-party libraries. And if these third-party libraries are not implemented in Objective-C++, then that third-party library will fail. Therefore, in order to avoid this method, it is foolproof for us to modify the .mm file. Of course, if you don't plan to use other third-party libraries, you can also modify the compilation method. Its actual path in Xcode 6 is: Build Settings -> Apple LLVM 6.0 - Language -> Compile Sources As.
Environment configuration
Select project settings in Xcode, navigate to Build Settings -> Linking -> Other Linker Flags, double-click to add -ObjC identifier. As shown in the figure:

Add -ObjC identifier

The reason for using this identifier is related to an important feature of Objective-C: category. Since Objective-C does not define linkage symbols for each function (or method), it only creates linkage symbols for each class. In this way, when a category is used in a static library to extend an existing class, the linker does not know how to integrate the original methods of the class with the methods in the category, which will cause "selector not recognized" , that is, the error that the method definition cannot be found. In order to solve this problem, the -ObjC flag was introduced, and its function is to load all object-related files in the static library.

Framework static library configuration method
If we download the framework static library framework file, then the configuration process is as follows:
import the framework
The downloaded framework files are divided into frameworks suitable for real devices and suitable for simulators, which are stored in the libs/Release-iphoneos file folder and libs/Release-iphonesimulator folder. We can choose the appropriate framework according to the device we are debugging.
If you need to debug on both the real machine and the emulator, you need to use the UNIX command lipo to merge these two files.
Let me teach you a very simple method! We drag the two folders Release-iphoneos and Release-iphonesimulator to your system root directory (usually your user name, there are also downloads, pictures, etc. directories under this directory, or use "Go" -> " Personal", or use the shortcut key "Shift + Command + H" to go to).
Then open the "Terminal" application, and if nothing else happens, enter the code
lipo -create Release-iphoneos/BaiduMapAPI.framework/BaiduMapAPI Release-iphonesimulator/BaiduMapAPI.framework/BaiduMapAPI -output BaiduMapAPI
to successfully create a new BaiduMapAPI file. As shown in the picture:

terminal input


merged successfully

Next, just replace the BaiduMapAPI file in the Release-iphoneos or iphonesimulator folder with this file.
Select the project in Xcode, click the "+" button in TARGETS -> Build Phases -> Link Binary With Libaries, click the "Add Other" button in the pop-up window, select the replaced BaiduMapAPI.framework file and add it to the project. As shown in the figure:

Import the framework

and import the resource file
Baidu map stores the resource image in the mapapi.bundle file, so we need to import this file into the project, otherwise the basic map cannot be displayed normally.
Open the BaiduMapAPI.framework file, and then import the mapapi.bundle file into the project. Remember to check the Copy items if needed option.

.a static library configuration method
If we download the .a static library framework file, then the configuration process is as follows:
Import static library files
Baidu map SDK official website gives three ways to import static library files, but according to my From experience, the most suitable method is the third method.
The third way is
to set the link path of the static library. Also in the project settings, navigate to Build Settings -> Search Paths -> Library Search Paths to add the static library directory. The general setting is $(PROJECT_DIR)/libs/Release$(EFFECTIVE_PLATFORM_NAME). $(PROJECT_DIR) refers to the directory location of the project, and $(EFFECTIVE_PLATFORM_NAME) represents whether the current configuration is OS or simulator. As shown in the figure:

Set the link path of the static library

The second way
The second method is similar to the method of "importing the framework static library". Both use the lipo command to merge files, but this time the .a files are merged.
Then open the "Terminal" application, enter
lipo -create Release-iphoneos/libbaidumapapi.a Release-iphonesimulator/libbaidumapapi.a -output libbaidumapapi.a
This code can successfully create a new .a file. As shown in the figure:

terminal input


merged successfully!


Import the system framework
According to Baidu's official instructions, import CoreLocation.framework, QuartzCore.framework, OpenGLES.framework, SystemConfiguration.framework, CoreGraphics.framework, Security.framework. The import method is also to locate the project settings, and then add it in General -> Linked Frameworks and Libraries.
Info.plist Settings
Positioning function prompt
Since iOS 8, Apple requires the positioning function to prompt the user whether to allow the use of geographical location. Therefore, it needs to be added in info.plist (choose one of the following two options, both of which are added by default using NSLocationWhenInUseUsageDescription):

NSLocationWhenInUseUsageDescription , which allows to obtain the description of GPS when using it in the foreground
NSLocationAlwaysUsageDescription, which allows permanent use of GPS description

As shown in the figure:

Add GPS description

In addition, in the process of using Xcode6 for SDK development, you need to add: Bundle display name in info.plist, and its value cannot be empty (the new project of Xcode6 does not have this configuration, if not, it will cause manager start failed). Here we add $(PRODUCT_NAME), which is the project name. As shown in the figure:

Add Bundle display name

HTTPS configuration
Since iOS 9, Apple requires the use of the more secure HTTPS protocol for data transmission, and avoid using the HTTP protocol as much as possible. Therefore, you need to add in info.plist:
<key> NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
As shown in the figure:
Thanks @JohnSmith for the reminder

Well, the initial configuration of the Baidu Maps SDK is over, and now you The project should be able to successfully compile. If there is a compilation error, please recheck whether the configuration is correct.
Initialize BMKMapManager
Add relevant initialization code in the AppDelegate.swift file to complete the initialization of BMKMapManager. The specific explanation is in the code:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {     var window: UIWindow?     var mapManager: BMKMapManager?     func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { //         Override point for customization after application launch.         mapManager = BMKMapManager() // Initialize BMKMapManager         // If you want to pay attention to network and authorization verification events, please set the generalDelegate parameter         let ret = mapManager?.start("Enter your authorization key here", generalDelegate: nil) // Pay attention to this When ret is Bool? Type         if !ret! { // If ret is false, first in the back! Forced unpacking, again in front! Invert             NSLog("manager start failed!") // It is recommended to use NSLog here, of course you can also use println         }












        self.window?.addSubview(navigationController!.view) // The following two sentences are completely unnecessary if you don’t use navigationController
        self.window?.makeKeyAndVisible()
        return true
    }
...
}
Create BMKMapView
and locate it in ViewController.swift file , you can create a BMKMapView.
The sample code is as follows:
class ViewController: UIViewController, BMKMapViewDelegate {     var mapView: BMKMapView!     override func viewDidLoad() {         super.viewDidLoad()         // Do any additional setup after loading the view, typically from a nib.         mapView = BMKMapView(frame: self .view.frame)         self.view = mapView     }     override func viewWillAppear(animated: Bool) {











        mapView.viewWillAppear()
        mapView.delegate = self // Remember to set nil here when not in use, otherwise it will affect the release of memory
    }

    override func viewWillDisappear(animated: Bool) {         mapView.viewWillDisappear()         mapView.delegate = nil // No use When , set nil     } ... } It should be noted that this class must follow the BMKMapViewDelegate protocol, otherwise the proxy settings cannot be used. BMKMapView adds viewWillAppear and viewWillDisappear methods to control the life cycle of BMKMapView, and only one BMKMapView can receive callback messages at a time, so in the viewController using BMKMapView, it is necessary to call the corresponding method of BMKMapView in the viewWillAppear and viewWillDisappear methods, and process acting. Compile and run on the emulator, the effect is shown in the figure below: Simulator running Positioning function The positioning function used by Baidu Maps is actually the positioning function that comes with the system, and Baidu Maps is only encapsulated. Therefore, the difficulty of our use is greatly reduced.












First of all, we still locate in the ViewController.swift file, and first follow the BMKLocationServiceDelegate protocol for this class. Then create a variable to hold the location services settings. The specific code is as follows:
class ViewController: UIViewController, BMKMapViewDelegate, BMKLocationServiceDelegate {     ...     var locService: BMKLocationService!     override func viewDidLoad() {         ...     // Set the location accuracy, default: kCLLocationAccuracyBest         BMKLocationService.setLocationDesiredAccuracy(kCLLocationAccuracyB est)         //Specify the minimum Distance update (meters), default: kCLDistanceFilterNone         BMKLocationService.setLocationDistanceFilter(10)         //Initialize BMKLocationService         locService = BMKLocationService()         //Start LocationService         locService.startUserLocationService()















        mapView.showsUserLocation = false
        //Set the location tracking state
        mapView.userTrackingMode = BMKUserTrackingModeNone
        //Display the positioning layer  
        mapView.showsUserLocation = true
    }

//Implement related delegates to process location information updates  
//Process direction change information
    func didUpdateUserHeading(userLocation: BMKUserLocation! ) {         mapView.updateLocationData(userLocation)     } //Process location coordinate update     func didUpdateBMKUserLocation(userLocation: BMKUserLocation!) {         mapView.updateLocationData(userLocation)     }     override func viewWillAppear(animated: Bool) {         ...         locService.delegate = self     }













    override func viewWillDisappear(animated: Bool) {         ...         locService.delegate = nil     } ... } There are many optional values ​​for setting location accuracy, roughly including the following: kCLLocationAccuracyBest: the highest accuracy when the device is powered by battery kCLLocationAccuracyBestForNavigation : The highest accuracy in navigation, generally only when there is an external power supply . : Do not track user location BMKUserTrackingModeFollow: Track user location BMKUserTrackingModeFollowWithHeading: Track user location and track user direction After compiling and running, the following interface appears: Prompt whether to allow the use of positioning
























This is the content we set in the Info.plist file before. Here we choose Allow to allow the use of positioning.
In the iOS simulator, how to simulate the location? In fact, it is very simple. Navigate to Debug -> Location -> Custom Location, and enter the latitude and longitude of the destination location in the pop-up dialog box, as shown in the figure. Here I input the latitude and longitude of Tiananmen Square (39'9076'', 116'391'').

Set the latitude and

longitude After setting the latitude and longitude, you can see the simulated geographic location on the map, which is displayed as a small blue dot.

Successful positioning

In addition, we can also use the "area simulation" of the debugging area to realize the positioning function, as shown in the figure. However, the simulation area provided by "Regional Simulation" is relatively small, and there are only some classic urban areas:

Regional Simulation

Note:


The positioning frequency and positioning accuracy should not be as accurate as possible. It depends on the actual situation, because the more accurate the more expensive The higher the performance, the more power it consumes.


After using the location service, if you do not need real-time monitoring, you should turn off the location service immediately to save resources.


There is no need to specify the center point in iOS8, the system will set the current location as the center point and automatically set the range of the displayed area by default.


Conclusion
Regarding the Swift version of Baidu Maps, I released a small demo on Github, basically referring to the demo provided by Baidu's official website. The demo version is still being updated and produced, so please look forward to it~

 

Guess you like

Origin blog.csdn.net/gaowenhui2008/article/details/51968435