Google 放置 API Web 服务使用 swift returns 错误 303
Google Places API web service using swift returns error 303
我正在尝试通过 iOS(使用 swift)使用 Google Places Web 服务。
我想这样做的原因 - 我想允许浏览地图上的地点,即使它们不在附近(唯一允许使用 iOS 提供的库进行搜索)。
我还需要以编程方式执行此操作(因为在一个用例中我想允许浏览地图,而在另一个用例中 - 我希望这些地方保持不变而不是根据地图相机进行更改)。
我不能使用 iOS 地点选择器,因为我希望地图显示有关其上地点的信息(并且在一个用例中不更改)...
(如果你对这个问题有更好的设计思路,请告诉我..)
调用 Google Places API 网络服务时出现错误 303。
在 Google API 网络服务上,它不计算调用次数,所以我认为它失败了,尽管 303 应该被重定向。
我构建了一个 class 用于与 Web 服务通信(我在配置中保存了服务器地址)。
class 的结构也可以立即提供结果(而不是在回调中)。
为什么我得到的是错误而不是重定向?
有办法处理吗?
关于如何避免重定向有什么想法吗?
谢谢!!
这是我的代码的(模板)——我减少了很多逻辑并保留了对 Web 服务的调用(PlaceMarker 只是一个 class I return,您可以修改它到字符串):
class GooglePlacesWS : NSObject, NSURLConnectionDelegate, NSURLConnectionDataDelegate , URLSessionDelegate{
var DataReady : Bool!;
var Data : Foundation.Data!;
var opQueue : OperationQueue!;
var _responseData : NSMutableData!;
var error = false;
func getPlacesNear(_ point : CLLocationCoordinate2D, _ radius: Double)->[PlaceMarker]!
{
var retVal = [PlaceMarker]();
var locationJson = ["location": String(format:"%f, %f",point.latitude,point.longitude), "key": “MyKey”];
if (radius > 0){
locationJson["raidus"] = String(format:"%d",Int(radius));
}
// Fires the request to the server
var reply : String = HtmlToText(FireRequest(locationJson));
if reply == "" { return nil}
return retVal;
}
//MARK: Connection
var session : URLSession? = nil;
var dataTasks : URLSessionTask? = nil;
func sendRequestNew(_ request : URLRequest)
{
DataReady = false;
Data = nil;
let task = session!.dataTask(with: request, completionHandler: {data, response,error in
if (error != nil){
NSLog("Error reading data from web service: " + error!.localizedDescription);
self.Data = nil;
self.error = true;
self.DataReady = true;
}
else{
if (data != nil){
self.Data = data;
OSMemoryBarrier();
self.DataReady = true;
}
}
});
task.resume();
dataTasks = task;
}
// Changes a string to an HTML friendly tags (so the XML will transfer a string)
func textToHtml (_ htmlString : String) -> String
{
var retHtml = htmlString;
retHtml = retHtml.replacingOccurrences(of: "&", with: "&");
retHtml = retHtml.replacingOccurrences(of: "<", with: "<");
retHtml = retHtml.replacingOccurrences(of: ">", with: ">");
retHtml = retHtml.replacingOccurrences(of: "\"", with: """);
retHtml = retHtml.replacingOccurrences(of: "'", with: "'");
//retHtml = retHtml.stringByReplacingOccurrencesOfString("\n", withString: "<br>");
return retHtml;
}
// Changes an HTML string to a regular xml (changes the & tags to actual signs)
func HtmlToText(_ textString : String)->String
{
var retString: String = textString;
retString = retString.replacingOccurrences(of: "&", with:"&");
retString = retString.replacingOccurrences(of: "<", with:"<");
retString = retString.replacingOccurrences(of: ">", with:">");
retString = retString.replacingOccurrences(of: """, with:"\"");
retString = retString.replacingOccurrences(of: "'", with:"'");
retString = retString.replacingOccurrences(of: "<br>", with:"\n");
return retString;
}
// Sends the request to the server
func FireRequest (_ query : [String:String]) ->String
{
var retVal : String = "";
do{
// Builds the final URL request (adds the headers, and the WS addy)
let config :UserDefaults = UserDefaults();
//var myDict: NSDictionary?
if let path : String = config.object(forKey: "googleServerAddy") as? String
{
let url = URL(string: path);
//let theRequest = NSMutableURLRequest(url: url!);
var request = URLRequest(url: url!);
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "GET";
request.httpBody = try JSONSerialization.data(withJSONObject: query, options: []);
sendRequestNew(request);
while (DataReady == false)
{
Thread.sleep(forTimeInterval: 0.01);
}
if (!error)
{
let result : Foundation.Data = Data!;
// Reads the response...
retVal = NSString(data: result, encoding:String.Encoding.utf8.rawValue)! as String;
}
else
{
retVal = "";
}
}
}
catch{
}
return retVal;
}
//MARK: NSURLConnection delegates
func connection(_ connection: NSURLConnection, willSend request: URLRequest, redirectResponse response: URLResponse?) -> URLRequest? {
return request;
}
override init() {
super.init();
opQueue = OperationQueue();
session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: opQueue);
}
}
您可以使用 Alamofire,效果很好。用于 google 街景图像
import Foundation
import Alamofire
import AlamofireImage
class GoogleData {
static let dataService = GoogleData()
func getGoogleImages(_ latitude: Double, longitude: Double, heading: Double, id: String, key: Int){
let url = "https://maps.googleapis.com/maps/api/streetview?size=400x300&location=" + String(latitude) + "," + String(longitude) + "&heading=" + String(heading) + "&fov=120&&pitch=-0.76&key=" + GOOGLE_API_KEY
Alamofire.request(url).responseImage { (response) -> Void in
print(response)
guard let image = response.result.value else { return }
print("alamo \(url) ")
let returnObj = [image]
ImageUtils.saveGoogleImageToFile(image , key: key, id: id)
NotificationCenter.default.post(name: NSNotification.Name(rawValue: googleGetImagesNotificationKey), object: returnObj)
}
}
}
调用它:
GoogleData.dataService.getGoogleImages(yourlatitude, longitude: your.longitude, heading: someHeading, id: someId, key: someKey )
所以我遇到的问题出自这里:
let url = URL(string: path);
var request = URLRequest(url: url!);
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "GET";
request.httpBody = try JSONSerialization.data(withJSONObject: query, options: []);
看起来 - 此解决方案强制重定向。
我不知道函数 addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)
所以我想使用 httpBody 来传输 GET 数据,这显然是错误的...
将代码更改为:
let actPath = path + "?" + query;
let url = URL(string: actPath);
var request = URLRequest(url: url!);
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "GET";
帮我解决了这个问题。
注意 query
是获取字符串的查询——类似于
location=1.1, 2.2&radius=5&key=MY_KEY
我正在尝试通过 iOS(使用 swift)使用 Google Places Web 服务。 我想这样做的原因 - 我想允许浏览地图上的地点,即使它们不在附近(唯一允许使用 iOS 提供的库进行搜索)。 我还需要以编程方式执行此操作(因为在一个用例中我想允许浏览地图,而在另一个用例中 - 我希望这些地方保持不变而不是根据地图相机进行更改)。 我不能使用 iOS 地点选择器,因为我希望地图显示有关其上地点的信息(并且在一个用例中不更改)... (如果你对这个问题有更好的设计思路,请告诉我..)
调用 Google Places API 网络服务时出现错误 303。 在 Google API 网络服务上,它不计算调用次数,所以我认为它失败了,尽管 303 应该被重定向。
我构建了一个 class 用于与 Web 服务通信(我在配置中保存了服务器地址)。 class 的结构也可以立即提供结果(而不是在回调中)。
为什么我得到的是错误而不是重定向? 有办法处理吗? 关于如何避免重定向有什么想法吗?
谢谢!!
这是我的代码的(模板)——我减少了很多逻辑并保留了对 Web 服务的调用(PlaceMarker 只是一个 class I return,您可以修改它到字符串):
class GooglePlacesWS : NSObject, NSURLConnectionDelegate, NSURLConnectionDataDelegate , URLSessionDelegate{
var DataReady : Bool!;
var Data : Foundation.Data!;
var opQueue : OperationQueue!;
var _responseData : NSMutableData!;
var error = false;
func getPlacesNear(_ point : CLLocationCoordinate2D, _ radius: Double)->[PlaceMarker]!
{
var retVal = [PlaceMarker]();
var locationJson = ["location": String(format:"%f, %f",point.latitude,point.longitude), "key": “MyKey”];
if (radius > 0){
locationJson["raidus"] = String(format:"%d",Int(radius));
}
// Fires the request to the server
var reply : String = HtmlToText(FireRequest(locationJson));
if reply == "" { return nil}
return retVal;
}
//MARK: Connection
var session : URLSession? = nil;
var dataTasks : URLSessionTask? = nil;
func sendRequestNew(_ request : URLRequest)
{
DataReady = false;
Data = nil;
let task = session!.dataTask(with: request, completionHandler: {data, response,error in
if (error != nil){
NSLog("Error reading data from web service: " + error!.localizedDescription);
self.Data = nil;
self.error = true;
self.DataReady = true;
}
else{
if (data != nil){
self.Data = data;
OSMemoryBarrier();
self.DataReady = true;
}
}
});
task.resume();
dataTasks = task;
}
// Changes a string to an HTML friendly tags (so the XML will transfer a string)
func textToHtml (_ htmlString : String) -> String
{
var retHtml = htmlString;
retHtml = retHtml.replacingOccurrences(of: "&", with: "&");
retHtml = retHtml.replacingOccurrences(of: "<", with: "<");
retHtml = retHtml.replacingOccurrences(of: ">", with: ">");
retHtml = retHtml.replacingOccurrences(of: "\"", with: """);
retHtml = retHtml.replacingOccurrences(of: "'", with: "'");
//retHtml = retHtml.stringByReplacingOccurrencesOfString("\n", withString: "<br>");
return retHtml;
}
// Changes an HTML string to a regular xml (changes the & tags to actual signs)
func HtmlToText(_ textString : String)->String
{
var retString: String = textString;
retString = retString.replacingOccurrences(of: "&", with:"&");
retString = retString.replacingOccurrences(of: "<", with:"<");
retString = retString.replacingOccurrences(of: ">", with:">");
retString = retString.replacingOccurrences(of: """, with:"\"");
retString = retString.replacingOccurrences(of: "'", with:"'");
retString = retString.replacingOccurrences(of: "<br>", with:"\n");
return retString;
}
// Sends the request to the server
func FireRequest (_ query : [String:String]) ->String
{
var retVal : String = "";
do{
// Builds the final URL request (adds the headers, and the WS addy)
let config :UserDefaults = UserDefaults();
//var myDict: NSDictionary?
if let path : String = config.object(forKey: "googleServerAddy") as? String
{
let url = URL(string: path);
//let theRequest = NSMutableURLRequest(url: url!);
var request = URLRequest(url: url!);
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "GET";
request.httpBody = try JSONSerialization.data(withJSONObject: query, options: []);
sendRequestNew(request);
while (DataReady == false)
{
Thread.sleep(forTimeInterval: 0.01);
}
if (!error)
{
let result : Foundation.Data = Data!;
// Reads the response...
retVal = NSString(data: result, encoding:String.Encoding.utf8.rawValue)! as String;
}
else
{
retVal = "";
}
}
}
catch{
}
return retVal;
}
//MARK: NSURLConnection delegates
func connection(_ connection: NSURLConnection, willSend request: URLRequest, redirectResponse response: URLResponse?) -> URLRequest? {
return request;
}
override init() {
super.init();
opQueue = OperationQueue();
session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: opQueue);
}
}
您可以使用 Alamofire,效果很好。用于 google 街景图像
import Foundation
import Alamofire
import AlamofireImage
class GoogleData {
static let dataService = GoogleData()
func getGoogleImages(_ latitude: Double, longitude: Double, heading: Double, id: String, key: Int){
let url = "https://maps.googleapis.com/maps/api/streetview?size=400x300&location=" + String(latitude) + "," + String(longitude) + "&heading=" + String(heading) + "&fov=120&&pitch=-0.76&key=" + GOOGLE_API_KEY
Alamofire.request(url).responseImage { (response) -> Void in
print(response)
guard let image = response.result.value else { return }
print("alamo \(url) ")
let returnObj = [image]
ImageUtils.saveGoogleImageToFile(image , key: key, id: id)
NotificationCenter.default.post(name: NSNotification.Name(rawValue: googleGetImagesNotificationKey), object: returnObj)
}
}
}
调用它:
GoogleData.dataService.getGoogleImages(yourlatitude, longitude: your.longitude, heading: someHeading, id: someId, key: someKey )
所以我遇到的问题出自这里:
let url = URL(string: path);
var request = URLRequest(url: url!);
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "GET";
request.httpBody = try JSONSerialization.data(withJSONObject: query, options: []);
看起来 - 此解决方案强制重定向。
我不知道函数 addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)
所以我想使用 httpBody 来传输 GET 数据,这显然是错误的...
将代码更改为:
let actPath = path + "?" + query;
let url = URL(string: actPath);
var request = URLRequest(url: url!);
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "GET";
帮我解决了这个问题。
注意 query
是获取字符串的查询——类似于
location=1.1, 2.2&radius=5&key=MY_KEY