{
" refresh_token":"25.b55fe1d287227ca97aab219bb249b8ab.315360000.1798284651.282335-8574074",
" expires_in":2592000,
" scope":" public wise_adapt",
" session_key":"9mzdDZXu3dENdFZQurfg0Vz8slgSgvvOAUebNFzyzcpQ5EnbxbF+hfG9DQkpUVQdh4p6HbQcAiz5RmuBAja1JJGgIdJI",
" access_token":"24.6c5e1ff107f0e8bcef8c46d3424a0e78.2592000.1485516651.282335-8574074",
" session_secret":"dfac94a3489fe9fca7c3221cbf7525ff"
}
{
"error": "invalid client",
"error description": "unknown client id"
}
#encoding:utf-8
import requests
#client_id 为官网获取的AK,client_secret 为官网获取的SK
host='https:
response = requests.get(host)
if response:
print(response.json())
acer
import requests
import base64
车型识别
'''
request_url ="https://aip.baidubce.com/rest/2.0/image-classify/v1/car"
#二进制方式打开图片文件
f= open('【本地文件]’,‘rb')
img=base64.b64encode(f.read())
params = ("image":img,"top_num":5)
access_token =【调用鉴权接口获取的token]
request url = request_url+"?access_token="+ access toker
headers = ('content-type': 'application/x-www-form-uriencoded'
response= requests.post(request_url,data-params, headers=headers
if response:
print (response.json())
返回的 JSON 数据:
"log_id”:4086212218842203806,
"location result":(
"width":447,
"top":226,
"height":209,
"left":188
),
"result":[(
"baike info":(
"baike url":"http:
"description":"布加迪Chiron是法国跑车品牌布加迪出品的豪华超跑车。配置四涡轮增压发动机,420 公里每小时,有23种颜色的选择,售价高达260万美元。”
),
"score":0.98793351650238,
"name":"布加迪Chiron",
"year":”无年份信息”
},
{
"name":“奥迪 RS5",
"score":0.0021970034576952,
"year":"2011-2017”
},
{
"score":0.0021096928976476,
"name":”奥迪RS4",
”year":”无年份信息”
},
{
"score":0.0015581247862428,
"name":“奥迪 RS7",
"year":"2014-2016"
},
{
"score":0.00082337751518935,
"name":”布加迪威航”,
"year":"2004-2015"
},
{
"color_result":"颜色无法识别”
}
数据接口与JSON
{
"Name":"Chen Zhifeng",
"Profession" : "Teacher",
"Age": 46,
"Email":"13402506301@163.com"
"Friends": ["Zhang San","Li Si"]
}
{
"TeamName":"iOS-Orange-Team",
"Teacher":"Chen Zhifeng",
"Students":[
{"Name":"Zhang Bo","Hometown": "Xuzhou"l},
{"Name":" Chang Wenxiang","Hometown":"Yancheng"},
{"Name":"Hu Yinting", "Hometown":"Suzhou"}
]
}
{
"coord":("lon":-0.13,"lat":51.51),
"weather":【("id”:300,"main":"Drizzle","description":"lightintensity drizzle","icon":"09d"],
"base":"stations",
"main":{
"temp":280.32,
"pressure":1012,
"humidity":81,
"temp_min":279.15,
"temp_max":281.15
},
"visibility":10000,
"wind":("speed":4.1,"deg":80).
"clouds":("all":901,
"dt":1485789600,
"sys":{
"type":1,
"id":5091,
"message":0.0103,
"country":"GB",
"sunrise":1485762037,
"sunset":1485794875
},
"id":2643743,
"name":"London"
"cod":200
}
6.1.3数据JSON解析实例
# myjson.js
module.exports = function() {
var data = users: []}
for(var i=0; i< 1000;i++){
data.users.push({id: i, name: 'user'+i})
}
return data
}
# news.js
let Mock =require('mockjs');
let Random = Mock.Random;
module.exports = function() {
var data={
news: []
};
var images =[1,2,3].map (x=>Random.image('200×100',Random.color()Random.word(2,6)));
for (var i = 0; i < 100;i++) {
var content = Random.cparagraph(0,10);
data.news.push({
id:i,
title: Random.cword(8,20),
desc: content.substr(0,40),
tag: Random.cword(2,6),
views: Random.integer(100,5000),
images: images.slice(0,Random.integer(1,3))
})
}
return data
}
import UIKit
import Foundation
if let url = URL(string: "http://localhost:3004/news") {
URLSession.shared.dataTask(with: url) ( (data, response,error) in
if error !=nil {
print("Network errors")
}
else {
let rs = String (data: data!, encoding: String.Encoding.utf8)!
print(rs)
if let json = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments){
print(json)
}
}
.resume()
}
6.2网络访问URL
func sessionGetData(){
let urlString= "http://www.tuling123.com/"
let url =URL(string:urlString)
let request = URLRequest(url:url!)
let session = URLSession.shared
let dataTask = session.dataTask(with: request,
completionHandler: {(data, response, error) -> Void in
if error != nil{
print(error.debugDescription)
}elsef {
let str = String(data: data!, encoding:String.Encoding.utf8)
print(str!)
}
}) as URLSessionTask
dataTask.resume ()
}
使用全局的 URLSession.shared和dataTask方法创建。通过下载指定的图片文件到应为任 K
序的Documents目录中,采用了时间戳,保证文件不会重名,示例程序如下:
func sessionDownloadImage()( M 0Alt Gr
let url = URL(string:"http://hangge.com/blog/images/logo.png")
let request = URLRequest (url: url!)
let session = URLSession.shared
let downloadTask = session.downloadTask(with: request,completionHandler: {(location:URL?, response:URLResponse?, error:Error?)
-> void in
print("location:\(String(describing: location))")
let locationPath = location?.path
let now = NSDate()
let timeInterval:TimeInterval = now.timeIntervalSince1970
let timeStamp = String(timeInterval)
let documents:String = NSHomeDirectory()+"/Documents\(timeStamp).png”
//创建文件管理器
let fileManager = FileManager.default
try! fileManager.moveItem(atPath: locationPath!,toPath:documents)
print("new location:\(documents)")
})
//使用 resume 方法启动任务
downloadTask.resume()
2.服务器设置和文件上传
$ sudo apachectl start | stop|restart
#LoadModule php5_module libexex/apache2/libphp5.so
$ sudo cp /etc/phc.ini.default /etc/php.ini
<?php
phpinfo();
?>
<?php
/** php 接收流文件
* @param String $file接收后保存的文件名
* @return boolean
*/
function receiveStreamFile(SreceiveFile)
$streamData = isset (SGLOBALS|'HTTP_RAW_POST _DATA'])? SGLOBALS'HTTP_RAW_POST_DATA'J:''
if(empty(SstreamData)){
$streamData = file_get_contents('php://input');
}
if($streamData!= "){
$ret =file put_contents(SreceiveFile, $streamData, true);
}else{
$ret = false;
}
return $ret
$receiveFile = $_SERVER "DOCUMENT_ROOT"]."/uploadFiles/swift.png";
echo SreceiveFile;
$ret = recelveStreamFile(SreceiveFile);
echo json_encode(array('success'=>(bool)$ret));
?>
Upload Task上传文件:通常以文件的形式发送数据,支持后台上传,示例程序如下:
func sessionUploadPhp(){
let url= URL(string:"http://localhost/uploadswift.php")
let session = URLSession.shared
var request= URLRequest(url: url!, cachePolicy: .reloadIgnoringCacheData)
request.httpMethod="POST"
let fileImage = Bundle.main.path(forResource:"beel", ofType:"png")
let imgData = try! Data(contentsOf: URL(fileURLWithPath: fileImage!))
let uploadTask = session.uploadTask(with:recuest as URIReouest, fron imgData){
(data:Data?, response:URLResponse?, error:Error?)-Void in
if error != nil{
print(error!)
}elsef{
let str = String(data: data!, encoding: String.Encoding.utf8
print("上传完毕:\(String(describing:str))")
}
}
uploadTask.resume()
}
6.2.2 车型识别能力的调用
具体程序根据用户的APL Key和Secret_Key来生成一个访问网址.然后使用URLSession调用网络访问,返回的结果JSONSerialization进行JSON解析
import UIKit
import Foundatior
let API_Key = "EIpAlhdD715152EsiNqpU0E_"
let Secret_Key "p8EZWg4agjDOxABmKvBYSNy21YzGFqb_"
let token host "https://aip.baidubce.com/oauth/2.0/token?grant_type=client credentials&client_id=\(API_Key)&client_secret=\(Secret_Key)"
var access_token = ""
var expires in: Int32=0
if let url = URL(string: token host) {
URLSession.shared,dataTask(with: url) (data,response,error) in
if error != nil{
print("network error")
}
else {
if let json = try? JSONSerialization.json0bject(with:data!,options: allowFragments) as? [String :Any] {
access_token ison ["access_token" ]as! String
expires_in = json["expires_in"]as!Int32
print("------access_token------)
print(access_token)
print("--------expires_time------")
print(expires_in)
}
}
}
·resume()
}
else {
print("url error")
}
2.采用POST方法获取车型信息
//以文本或者二进制方式读入源程序文件的Loader
public struct Loader {
static func readTxt(file url:URL) -> String?
do {
let source = try String(contentsOf: url)
return source
}
catch {
return nil
}
}
static func readBin(file url:URL) ->Data?
do{
let data = try Data(contentsof: url)
return data
}
catch{
return nil
}
}
}
//Resources中的文件,并把路径转化为URL
let path = Bundle.main.path(forResource: "qrcar.jpg", ofType: nil)
let url = URL(fileURLWithPath:path!)
let data = Loader.readBin(file: url)
if(data == nil){
print("File failed to load")
}
let data_base64_str = data?.base64EncodedString()
let data_base64 = data?.base64EncodedData()
access token="24.2ec96a68f74a8429b0f07869929413ae.2592000.1598921312.282335-21737249"
let carType_host = "https:
if let url = URL(string: carType_host){
var request = URLRequest (url: url)
regvest.setValue("applicat.ion/x-ww-form-urlencoded",forfHeaderField: "Content-Type")
request.httpMethod ="POST"
let cs = NSCharacterSet(charactersIn:"/=+g").inverted
letimage_urlEncode=data_base64_str!.addingPercentEncoding(withAllowedCharacters: cs)
let postString="image=\(image_urlEncode!)&top_num=5&baike_num=1"
request.httpBody =postString.data(using: .utf8)
URLSession.shared.dataTask(with: request)((data, response, error) in
if error != nil {
print("error")
}
else{
let rs = String(data: data!, encoding: String.Encoding.utf8)
print(rs!)
}
}
.resume ()
}
最有可能的车型是“奇瑞E5”
{
"1og_id”:4368540366187197442,
"location_result":
{
"width":386.4585876464844,
"top":81.3405532836914,
"height":183.9795532226562,
"left":58.03330230712891
},
"result":
[
{
"score":0.9767324924468994,
"year":"2014-2017",
"baike_info":
{
"baike_url":"/item/BE58A58878E79189E65/475143”,
"image_url":
"/pic/5882b2b7d0a20cf47a91d7777c094b36acaf9910",
"description"
"2014 款奇瑞E5是国内科技家轿的引领者,带领消费者悦享领先科技",
},
"name": "奇瑞 E5"
},
{
"score":0.007103727199137211,
“name”:“奇瑞旗云”,
"year":"2010-2013”
},
{
"score":0.003686367534101009,
"name":“奇瑞艾瑞泽 7”,
"year":"2016-2017"
"score":0.001757977530360222,
"name":"奇瑞E3”
"year":"2015-2017"
},
{
"score":0.001047104829922318,
"name":"奇瑞A5".
"year":"2015"
},
{
"color result":"黑色”
}
6.3 项目实现
6.3.1 相册图片的显示
//
//ViewController.swift
//CameraUsage
//
//Created by Zhifeng Chen on 2020/8/2.
//Copyright 2020 Zhifeng Chen. All rights reserved.
//
import UIKit
class ViewController: UIViewController ,UINavigationControllerDelegat,UIImagePickerControllerDelegatel{
//设置图像显示用的Outlet,就是变量carImageView
@ZBOutlet weak var carImageView: UIImageView!
// 设置Action, 由相册按钮事件触发
@IBAction func onLibrary(_sender: UIButton) {
//设置相册拍照的控制器
let vc = UIImagePickerController()
//设置为相册
vc.sourcerype =.photoLibrary
vc,allowsEditing = true
vc.delegate = self
present(vc, animated: true)
}
//设置Action,由拍照按钮事件触发
@IBAction func onCamera(_sender:UIButton){
let vc = UIImagePickerController()
//设置为摄像头
vc.sourceType =.camera
vc.allowsEditing = true
ve.delegate = self
present (vc, animated: true)
//相册获取图片需要调用的Delegate
func imagePickerController( picker:
didFinishPickingMediaWithInfo info:[UIImagePickerController.InfoKey:Any])
picker.dismiss(animated: true)
guard let image = infol.editedImage] as? UIImage else
return
}
//将相册图片显示在carImageView中
carImageView.image = image
}
}
6.3.2 车型识别的实现
//
//ViewController.swift
//CameraUsage
//
//Created by Zhifeng Chen on 2020/8/2.
//Copyright 2020 Zhifeng Chen.All rights reserved.
//
import UIKiT
class ViewController: UIViewControllerDelegate,UIImagePickerControllerDelegatel{
//设置图像显示用的Outlet,就是变量carImageVieW!
@IBOutlet weak var carImageView:
//显示识别出来的车辆名称型号
@IBOutlet weak var carName: UILabel!
//显示该车辆百度百科里面的简介
@IBOutlet weak var carDetails: UILabel!
//设置Action,由相册按钮事件触发
IBAction func onlibrary(_ sender: UIButton)
//设置相册拍照的控制器
let ve = UIImagepickerController()
//设置为相册
vc.sourceType = .photoLibrary
vc.allowsEditing = true
vc.delegate = self
present(vc, animated: true)
}
//设置Action,由拍照按钮事件触发
@IBAction func onCamera( sender: UIButton)
let vc = UIImagePickerController()
//设置为摄像头
vc.sourceTvpe = .camera
vc.allowsEditing = true
vc.delegate = self
present(vc, animated: true)
}
//相册获取图片需要调用的 Delegate
fune imagePickerController( picker:UIImagePickerController didFinishPickingMediaWithInfo info:[UIImagePickerController.InfoKey: Any])
picker.dismiss (animated: true)
guard let image = info[.editedImage] as? UIImage else
return
}
// 将相册图片显示在carImageView中
carImageView.image image
//获得百度AI平台的access token
let access_token = get baidu token()
if access token =="" {
return
}
else {
//从百度 AI获得车型信息
get_car_type(access_token: access_token)
}
}
//传入有效的access _token,上传图片,获得车型信息
func get car type(access_token:String)
//获取显示的图片,并保存为 jpg 格式
let image = carImageView.image
//let data = UIImagePNGRepresentation(image)
guard let data = image!.jpegData(compressionQuality: 0.5) else return
//将图片进行base64编码
let data base64 str = data.base64EncodedString(
//准各好获取车型的API的URL的字符串
let carType_host = "https:
if let url = URL(string: carType_host)
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded", forHIlPHeaderField: "Content-Type")
request.httpMethod = "PosT"
let cs = NSCharacterSet(charactersIn:"/=+8").invertedlet image urlEncode = data base64_str.addingPercentEncodirg(withAllowedCharacters:cs)
let postString ="image=\(image_urlEncode!)stop_num=5abaike_num=111将字符串转为UTE8类型的数据
request.httpBody = poststring.data(using: .utf8)
//URLSession 调用
URLSession.shared.dataTask(with: request) (data, response, error) in
if error != nil
print("error")
}
else{
if let json = try? JSONSerialization.json0bject (with:data!, options: allowFragments) as? [String: Any]{
let result = json["result"] as! Array<Dictionarye
String,Any>> let name = result[0]["name"] as! String
var description="非车类”
if name !=”非车类”{
let baike info = result[0]("baike_info"] as!
Dictionarv<String,String>
if let details = baike_info["description"]
description =details
}
else {
description="百度百科无此车资料,
// 转入主线程
DispatchQueue.main.async {
self.carDetails.text = description
self.carName.text = name
.resume{
//以信号量方式等待网络结果返回access_token,如果没有成功,则返回“”func get_baidu_token()->String (
let API Key ="EIpAlhdD715152EsiNqpU0F1"
let Secret_Key ="p8EZWg4agjDOxABmKvBYSNyZ1YzGFqbm"
let token_host= "https:
var access token
// 设置信号量
let semaphore: DispatchSemaphore = DispatchSemaphore(value: 0)
if let url =URL(string: token host)
URtSession,shared.dataask (with:ur1) ((data, response, erzoz) in
if error != nil
print("network error")
}
else{
if let json = try? JSONSerialization.jsonbject(with:data!,ject(with: data!,options: .allowFragments) as? [String :Any]
access_token =json["access_token"] as! String
}
}
semaphore.signal()
}
.resume()
else{
print("url error")
}
semaphore.wait()
return access_token
}
}