私は過去数時間にわたって私の頭を壁に打ち倒しているという奇妙な問題があります。チタンHTTPClientが実行される前に結果が使用されない
私はAppcelerator TitaniumのiPhoneアプリで作業しています。現在、他のコードが実行されてから、HTTPClientリクエストの結果を得る前に待っています。その結果を使用してみてください。
function getMarkers(e, miles){ //The function with the HTTPClient calls that are firing last, trimmed to have only the relevant code.
var markers = [];
Ti.API.info("Getting markers");
xhr.onload = function()
{
var data = Ti.XML.parseString(this.responseText);
var ref = data.documentElement.getElementsByTagName("reference");
for(var i =0; i < ref.length; i++){
var marker = new Object();
marker.ref = ref.item(i).text;
var request = Titanium.Network.createHTTPClient();
request.setTimeout(10000);
request.onload = function(){
var data = Ti.XML.parseString(this.responseText);
marker.address = data.documentElement.getElementsByTagName("formatted_address").item(0).text;
if(data.documentElement.getElementsByTagName("formatted_phone_number") != null){
marker.phone = data.documentElement.getElementsByTagName("formatted_phone_number").item(0).text;
} else {
marker.phone = null;
}
marker.icon = data.documentElement.getElementsByTagName("icon").item(0).text;
marker.lat = data.documentElement.getElementsByTagName("lat").item(0).text;
marker.lng = data.documentElement.getElementsByTagName("lng").item(0).text;
marker.name = data.documentElement.getElementsByTagName("name").item(0).text;
if(data.documentElement.getElementsByTagName("url") != null) {
marker.url = data.documentElement.getElementsByTagName("url").item(0).text;
} else {
marker.url = null;
}
markers.push(marker);
Ti.API.info(markers.length);
}
request.open("GET","https://maps.googleapis.com/maps/api/place/details/xml?reference=" + marker.ref + "&sensor=true&key=" + Ti.App.apiKey);
request.send();
}
};
xhr.open("GET","https://maps.googleapis.com/maps/api/place/search/xml?location=" + googleLatLng + "&radius=" + radius + "&types=" + Ti.App.types + "&sensor=true&key=" + Ti.App.apiKey);
xhr.send();
return markers;
}
// actually draw the markers on the map
function drawMap(markers, currentLoc)
{
var i;
Ti.API.info("Adding markers...");
for(i=0;i<markers.length;i++)
{
Ti.API.info("Marker " + i);
Ti.API.info(markers[i].name);
var ann = Titanium.Map.createAnnotation({
image:markers[i].icon,
animate:true,
latitude:markers[i].lat,
longitude:markers[i].lng,
title:markers[i].name,
subtitle:markers[i].address
});
if(markers[i].url != null){
ann.rightButton = markers[i].url;
}
mapview.addAnnotation(ann);
}
Ti.API.info("Markers added"); //When this block is called, markers.length == 0
}
// find the user's location and mark it on the map
function waitForLocation(e)
{
//Do stuff about finding current location and marking it on the map. This stuff works and a pin drops for the current location
drawMap(getMarkers(e), currentLoc);
}
waitForLocationが最初に呼び出され、次にそれを呼び出します。 Xcodeは以下を出力します
[INFO] Getting markers
[INFO] Adding markers...
[INFO] Markers added
[INFO] 1
[INFO] 2
[INFO] 3
[INFO] 4
これは、それが、実際にマーカーを取得するために戻ってgetMarkers関数に行き、その後、(次の2行)、それを残して、getMarkers機能(最初の行)に起こっていることを意味します(最後の4各マーカーとしてmarkers.length
の出力が加えられる)。その
を知って、私はここで見つけるの回答に基づいて.onload()
コール前から.open()
呼び出しを移動し、私は.open()
の前か後に.onload()
であるかどうか、同じを取得します。
httpClient呼び出しが非同期にタスクを実行するという情報が見つかりました(API参照に欠けている重要な情報)。これを知っていると、それは機能を残しているのは理にかなっていますが、追加する前にダウンロードしたマーカーが必要なので、情報の処理方法には悩まされます。
iPhoneデベロッパーの同僚と話しているとき、彼はデリゲートとdelegate.connectionDidFinishLoadingコールを使用してそれらを処理すると述べました。おそらく、これにフックする方法か、これを使用できるチタニウムの実装がありますか?
アプリが実際にそれらをダウンロードする前にマーカーをロードしようとしないようにする良い方法がありますか?それはiPhoneのためだけに働く必要があるので、iPhone固有のオプションはうまくいきます。
私は正確に同じ問題をあなたの質問を見つけたことを追加したいと思います。 しかし、私はiPhoneとAndroidの両方を開発しています。Android(標準)では.open()の不思議な3番目のパラメータが動作しないことがわかりました。 – Cyntech
ええ、それはTiについて私を挫折させた事の一つです。私たちのAndroidとiPhoneのプロジェクトは分かれています(もちろん、Tiを使う目的の半分を奪っています)。しかし、それらを統合することさえできません。サポートレベル。 – Shauna