UPDATE: Fontos változás az ismerősök lekérdezésénél.
Az iWiW alkalmazások lekérdezhetik az alkalmazás tulajdonosának, illetve az alkalmazás nézőjének ismerőseit (erről már volt korábban szó: Mit tehet egy alkalmazás?), ám ezt illetően vannak kötöttségek, például egy lekérdezés után alapértelmezetten csak 20 ismerőst kapunk vissza, s bár ezt meg lehet növelni, de a limit 50 ismerős - vagyis lapozni kell. Az alábbiakban egy megoldást teszek közzé, mely felhasználóbarát módon teszi lehetővé az összes ismerős elérését.
A megoldás kulcsához nézzük át, hogy a newFetchPeopleRequest kérés milyen módon paraméterezhető:
- FILTER: Szűrhetjük az ismerősök listáját, például szűkíthetjük az ismerősök listáját azokra, akiknek a jelen alkalmazás már fel van telepítve. Jelenleg csak ezt a szűrési módot támogatja az iWiW.
- FILTER_OPTIONS: Egyes filterekhez lehet(ne) megadni további paramétereket segítségével.
- FIRST: Ezzel határozhatjuk meg, hogy hányadik ismerőstől kérjük a listát.
- MAX: Ezzel pedig azt, hogy maximum mennyi elemet kérünk (50-nél többet nem kérhetünk az iWiW-en).
- PROFILE_DETAILS: Milyen profil tulajdonságokat szeretnénk lekérni - jelenleg felesleges használni, de a jövőben amikor további profil információkhoz is hozzá lehet majd férni, akkor igen hasznos lesz.
- SORT_ORDER: Milyen sorrendben szeretnénk az ismerőseinket visszakapni. Jelenleg csak a névsort támogatja az iWiW, vagy ha nem adunk meg sorrendet, akkor valamilyen “véletlen” (belső azonosítóra épülő), de nem változó listát kapunk.
A trükkre az eddig írtakból rá lehet jönni: a FIRST és MAX paraméterek állításával fogjuk lekérdezni az összes ismerőst. Van még két trükk azonban: az egyik, hogy a kéréseket összecsomagolva csökkenthetjük a szerver felé indított kérések számát, illetve hogy először csak egy csomagot (50 ismerőst) kérünk le, s a válaszban benne levő teljes ismerősök száma tulajdonságot használjuk fel ahhoz hogy meghatározzuk, mennyi további csomagot fogunk lekérni (300 ismerősnél első kérésben 50-et, második kérésben 5 csomagban 5×50-et, avagy 250-et fogunk lekérni).
Ennek a felállásnak az is előnye, hogy az első válasz után már meg tudjuk jeleníteni a felhasználók felé az első adagot, s míg jön a többi, ő már elkezdhet tevékenykedni.
Ezekkel a funkciókkal, lehetőségekkel összeállítottam egy kész függvényt, mely ezeket a feladatokat megcsinálja mind helyettünk:
var IWIW = {}; IWIW.loadFriends = function(options) { // az objektumot később is fogjuk még használni, amikor a "this" más értékkel fog // bírni, ezért letároljuk az "obj" változóba var obj = this; // az ismerősök száma obj.totalSize = 0; // a params paraméterrel átadhatunk paramétereket a newFetchPeopleRequest hívásnak obj.params = options.params || {}; // az ismerősök lekérdezését a legelején kezdjük obj.params[opensocial.DataRequest.PeopleRequestFields.FIRST] = 0; // és 50-et kérünk le (iWiW-en az egy csomagban lekérhető maximum) obj.params[opensocial.DataRequest.PeopleRequestFields.MAX] = 50; // a userId paraméter segítségével megmondhatjuk, hogy az OWNER vagy VIEWER // ismerőseire vagyunk-e kíváncsiak var userId = options.userId; // az onFirstFriends egy függvény, mely akkor hívódik meg, amikor az első ismerős // csomag megérkezik var onFirstFriends = options.onFirstFriends || function(){}; // az onAllFriends egy függvény, mely akkor hívódik meg, amikor az összes ismerős // csomag megérkezett var onAllFriends = options.onAllFriends || function(){}; // egy adatlekérés objektumot hozunk létre var request = opensocial.newDataRequest(); // egy csoportot definiálunk: az alkalmazás nézőjének vagy tulajdonosának (userId) az ismerőseit obj.usergroup = opensocial.newIdSpec({"userId": userId, "groupId": "FRIENDS"}); // a kéréshez hozzáadjuk az előbb definiált csoport lekérdezését, a választ // "friends0" néven fogjuk visszakapni request.add(request.newFetchPeopleRequest(obj.usergroup, obj.params), "friends0"); // a függvény, mely az első adatlekérés után fut le var firstReady = function(response) { // itt a this értéke különbözik az eredeti objektumunktól, // ezért is használjuk az obj változót. // az obj.friends egy tömb lesz, melybe a válasz csomagokat pakoljuk obj.friends = [response.get("friends0").getData()]; // a válaszban benne van az az információ, hogy összesen mennyi ismerős van, letároljuk obj.totalSize = obj.friends[0].getTotalSize(); // a size értéke a jelen csomagban érkezett ismerősök száma (jellemzően 50, hacsak nincs // 50-nél kevesebb ismerőse a felhasználónak) var size = obj.friends[0].size(); // a pozíció, ahol az ismerősök listájával járunk (0, 50, 100, stb. lesz) var pos = 0; // ha nem jött meg az összes ismerős, akkor... if (size < obj.totalSize) { // meghívjuk az első ismerősök megérkezésekor lefutó függvényt onFirstFriends(obj); // egy adatlekérés objektumot hozunk létre var request = opensocial.newDataRequest(); // amíg nem érjük el az ismerősök számát... while (pos + size < obj.totalSize) { // következő csomag ott kezdődik, ahol az előző abbamaradt pos += size; // beállítjuk, hogy honnantól kezdje letölteni az ismerősöket, mi legyen az első elem obj.params[opensocial.DataRequest.PeopleRequestFields.FIRST] = pos; // a kéréshez hozzáadjuk a korábban már definiált csoport lekérdezését, a választ // "friendsXXX" néven fogjuk visszakapni, ahol az XXX a pozíció request.add(request.newFetchPeopleRequest(obj.usergroup, obj.params), "friends"+pos); } // elküldjük a több csomagot is tartalmazó kérést (második kérés) request.send(allReady); } else { // ha az első kérés során megjött az összes ismerős, akkor csak az onAllFriends kerül // meghívásra, mert már most tartalmazza az összes ismerőst. onAllFriends(obj); } } // a függvény, melyet a második lekérdezés válaszának megérkezésekor hívunk meg var allReady = function(response) { // csomag változó var package; // az első csomag végéről indulunk var pos = obj.friends[0].size(); // ha nem értünk a végére, akkor... while (pos < obj.totalSize) { // a csomagot kivesszük a válaszból var package = response.get("friends"+pos).getData(); // és betesszük az obj.friends tömbbe obj.friends.push(package); // növelkjük a pozíciót pos += package.size(); } // meghívjuk az onAllFriends függvényt az összes ismerőssel onAllFriends(obj); } // elküldjük a lekérdezést, a függvény paramétere egy másik függvény, // ami akkor kerül meghívásra, amikor a szervertől megérkezik a válasz request.send(firstReady); // visszatérünk az IWIW.loadFriends objektumunkkal, ez egyelőre elég üres // de már beindítottuk az első lekérdezést, melyre hamarosan megjön a válasz return this; };
A függvényt igyekeztem elég jól dokumentálni sok-sok megjegyzéssel, a kódban benne van tehát a magyarázat - emiatt nem írnám le még egyszer hogy pontosan hogyan működik. Összefoglalva: egy vagy két kérést indítunk a szerver felé, második kérést csak akkor, ha az első 50 elembe nem fért bele az összes ismerős. A második kérésben annyi csomagban kérjük le az ismerősöket, hogy immár a teljes ismerősi kör beleférjen. Paraméterként két függvényt adhatunk át, az első az első kérés után fut le (ha nem jött meg az összes ismerős), míg a második akkor, ha megjött az összes. A megkapott objektum friends tömbjében lesznek benne a szervertől visszakapott válaszok.
A függvény használatára egy példa, így valószínűleg még érthetőbb lesz:
// új kérés new IWIW.loadFriends({ // a tulajdonos ismerőseit fogjuk lekérdezni userId: "OWNER", // ha megjött az első adag ismerős onFirstFriends: function(response) { // az objektum friends tulajdonsága a fentebb emlegetett tömb var friends = response.friends; // a friends tömbnek még csak egy eleme van friends[0].each(function(person){ // person.getDisplayName() használható, például }) }, // ha megjött az összes ismerős onAllFriends: function(response) { // az objektum friends tulajdonsága a fentebb emlegetett tömb var friends = response.friends; // végigmegyünk a tömb elemein, a csomagokon for(var i=0; i<friends.length; i++) { // minden csomagból kiolvassuk a benne levő személyeket friends[i].each(function(person){ // person.getDisplayName() használható, például }) } } });
Nem egészen értem, hogy minek leszűkiteni hogy mennyi ismerőst tudunk lekérni, ha azután kapunk egy eszközt ennek a megkerülésére?
Amúgy kösz az eszközt, (felhasználhatjuk, ugye?) megsporoltál egy adag melót!
Akos: Mert ez nem az az eszköz amit mindig használni kell, de elképzelhetőek olyan funkciók, amikhez szükséges lehet az összes ismerős lekérdezése. Azért mert írtunk róla, továbbra sem támogatjuk azt, ha valaki indokolatlanul kérdezi le az összes ismerőst egy alkalmazásban. A jóváhagyási folyamatnak ezért is része az alkalmazás technikai ellenőrzése.