0

iOS経由でGoogleプレイスWebサービスを使用しようとしています(swiftを使用しています)。 私がそうしたい理由 - 近くにいなくても、地図上の場所を閲覧できるようにしたい(iOS提供のライブラリを使って唯一の検索が許可されている)。 また、プログラムで行う必要があります(あるユースケースでは、マップをブラウズできるようにしたい、別のユースケースでは、マップカメラに基づいて場所を一定にして変更しないでください)。 iOSプレースピッカーを使用することはできません。地図上にプレースに関する情報を表示したい(1つのユースケースでは変更しないでください)... 、私に教えてください)GoogleプレイスAPI Webサービスでスワップ返却エラー303

Google Places APIウェブサービスを呼び出すと、エラー303が表示されます。 Google APIウェブサービスではコールはカウントされないため、失敗したと見なしますが、303はリダイレクトする必要があります。

Webサービスと通信するためのクラスを作成しました(構成にサーバーアドレスを保存します)。 このクラスも、すぐに結果を提供するように構造化されています(コールバックではありません)。

なぜリダイレクトではなくエラーが発生しますか? これを処理する方法はありますか? リダイレクトを回避するために何ができるのですか?

ありがとうございます!

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: "&lt;"); 
    retHtml = retHtml.replacingOccurrences(of: ">", with: "&gt;"); 
    retHtml = retHtml.replacingOccurrences(of: "\"", with: "&quot;"); 
    retHtml = retHtml.replacingOccurrences(of: "'", with: "&#039;"); 
    //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: "&amp;", with:"&"); 
    retString = retString.replacingOccurrences(of: "&lt;", with:"<"); 
    retString = retString.replacingOccurrences(of: "&gt;", with:">"); 
    retString = retString.replacingOccurrences(of: "&quot;", with:"\""); 
    retString = retString.replacingOccurrences(of: "&#039;", 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); 
    } 
} 
:私は私のロジックの多くを削減し、Webサービスの呼び出しを左(PlaceMarkerは、あなたが文字列にそれを修正することができ、私は返すだけのクラスです) - ここ

は、私のコードの(テンプレート)です

答えて

0

だから私が持っていた問題が、ここで供給されます:

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: []); 

表示されます - このソリューションは、リダイレクトを強制します。 私は、コードを変更する...ので、私は明らかに間違っている、GETデータを転送するためhttpBodyを使用したい

機能addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)を認識していませんでした:

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"; 

は私のために問題を解決しました。私はそれがどのようにエレガント好き

場所= 1.1、2.2 &半径= 5 &キーのようなもの= MY_KEY

1

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) 
+0

が、今では手遅れ - 予告queryは、get文字列のクエリです私のプロジェクトにこのライブラリを追加するために私は問題が何かを理解しました - この質問に対する私の他の答えを見てください...ありがとうございます。おそらく私の次のプロジェクトのためにこのライブラリを試してみます。 – evenro

+0

あなたはそれを考慮する必要があります、本当に簡単にネットワークを作る、歓声 – ppoh71

関連する問題