Let’s know have a look at network geolocation on iOS. I’ve done the test using an iPad 3G running iOS 4.2.1
The way iOS geolocates the mobile is much different from Android. As you’ll see hereunder, the Apple Maps application downloads a subset of the Wifi and Cellular databases around the mobile’s actual position and calculates the mobile location locally ; whereas, on Android, Google calculates the mobile location on their servers and sends it back to the Android device.
Here’s an Apple POST request to https://iphone-services.apple.com/clls/wloc which downloads a subset of the Wifi location database from Apple servers :
00000000 50 4f 53 54 20 68 74 74 70 73 3a 2f 2f 69 70 68 |POST https://iph| 00000010 6f 6e 65 2d 73 65 72 76 69 63 65 73 2e 61 70 70 |one-services.app| 00000020 6c 65 2e 63 6f 6d 2f 63 6c 6c 73 2f 77 6c 6f 63 |le.com/clls/wloc| 00000030 20 48 54 54 50 2f 31 2e 31 0a 0a 50 4f 53 54 20 | HTTP/1.1..POST | 00000040 68 74 74 70 73 3a 2f 2f 69 70 68 6f 6e 65 2d 73 |https://iphone-s| 00000050 65 72 76 69 63 65 73 2e 61 70 70 6c 65 2e 63 6f |ervices.apple.co| 00000060 6d 2f 63 6c 6c 73 2f 77 6c 6f 63 20 48 54 54 50 |m/clls/wloc HTTP| 00000070 2f 31 2e 31 0a 48 6f 73 74 3a 20 69 70 68 6f 6e |/1.1.Host: iphon| 00000080 65 2d 73 65 72 76 69 63 65 73 2e 61 70 70 6c 65 |e-services.apple| 00000090 2e 63 6f 6d 0a 55 73 65 72 2d 41 67 65 6e 74 3a |.com.User-Agent:| 000000a0 20 6c 6f 63 61 74 69 6f 6e 64 20 28 75 6e 6b 6e | locationd (unkn| 000000b0 6f 77 6e 20 76 65 72 73 69 6f 6e 29 20 43 46 4e |own version) CFN| 000000c0 65 74 77 6f 72 6b 2f 34 38 35 2e 31 32 2e 37 20 |etwork/485.12.7 | 000000d0 44 61 72 77 69 6e 2f 31 30 2e 34 2e 30 0a 58 2d |Darwin/10.4.0.X-| 000000e0 41 70 70 6c 65 2d 42 75 6e 64 6c 65 69 64 3a 20 |Apple-Bundleid: | 000000f0 63 6f 6d 2e 61 70 70 6c 65 2e 4d 61 70 73 0a 41 |com.apple.Maps.A| 00000100 63 63 65 70 74 3a 20 2a 2f 2a 0a 41 63 63 65 70 |ccept: */*.Accep| 00000110 74 2d 4c 61 6e 67 75 61 67 65 3a 20 65 6e 2d 75 |t-Language: en-u| 00000120 73 0a 41 63 63 65 70 74 2d 45 6e 63 6f 64 69 6e |s.Accept-Encodin| 00000130 67 3a 20 67 7a 69 70 2c 20 64 65 66 6c 61 74 65 |g: gzip, deflate| 00000140 0a 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 61 |.Content-Type: a| 00000150 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 77 77 77 |pplication/x-www| 00000160 2d 66 6f 72 6d 2d 75 72 6c 65 6e 63 6f 64 65 64 |-form-urlencoded| 00000170 0a 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a |.Content-Length:| 00000180 20 31 35 32 0a 0a 00 01 00 05 65 6e 5f 55 53 00 | 152......en_US.| 00000190 00 00 0b 34 2e 32 2e 31 2e 38 43 31 34 38 00 00 |...4.2.1.8C148..| 000001a0 00 01 00 00 00 78 12 12 0a 10 30 3a 32 35 3a 31 |.....x....0:25:1| 000001b0 35 3a 61 39 3a 34 63 3a 66 38 12 12 0a 10 32 3a |5:a9:4c:f8....2:| 000001c0 32 35 3a 31 35 3a 61 39 3a 34 63 3a 66 61 12 12 |25:15:a9:4c:fa..| 000001d0 0a 10 32 3a 32 35 3a 31 35 3a 61 39 3a 34 63 3a |..2:25:15:a9:4c:| 000001e0 66 39 12 11 0a 0f 35 63 3a 33 33 3a 38 65 3a 61 |f9....5c:33:8e:a| 000001f0 3a 31 36 3a 62 12 13 0a 11 33 36 3a 66 66 3a 38 |:16:b....36:ff:8| 00000200 38 3a 65 65 3a 36 34 3a 62 38 18 00 20 00 2a 0e |8:ee:64:b8.. .*.| 00000210 63 6f 6d 2e 61 70 70 6c 65 2e 4d 61 70 73 |com.apple.Maps|
Different things can be highlighted :
- Most part of the request is encoded the Google “Protocol Buffers” ; does it mean that Apple’s geolocation service is run by some Google technologies ?
- The request is short and contains only mandatory information (the WIFI Mac adresses)
The “Protocol Buffers” part is decoded this way :
2 {
1: "0:25:15:a9:4c:f8"
}
2 {
1: "2:25:15:a9:4c:fa"
}
2 {
1: "2:25:15:a9:4c:f9"
}
2 {
1: "5c:33:8e:a:16:b"
}
2 {
1: "36:ff:88:ee:64:b8"
}
3: 0
4: 0
5: "com.apple.Maps"
The response is quite long because it contains not less that 1542 entries containing the WIFI Mac adress and the position of the hotspot ; here’s the beginning of the response :
00000000 50 4f 53 54 20 68 74 74 70 73 3a 2f 2f 69 70 68 |POST https://iph| 00000010 6f 6e 65 2d 73 65 72 76 69 63 65 73 2e 61 70 70 |one-services.app| 00000020 6c 65 2e 63 6f 6d 2f 63 6c 6c 73 2f 77 6c 6f 63 |le.com/clls/wloc| 00000030 20 48 54 54 50 2f 31 2e 31 0a 0a 48 54 54 50 2f | HTTP/1.1..HTTP/| 00000040 31 2e 31 20 32 30 30 20 4f 4b 0a 44 61 74 65 3a |1.1 200 OK.Date:| 00000050 20 57 65 64 2c 20 30 32 20 46 65 62 20 32 30 31 | Wed, 02 Feb 201| 00000060 31 20 31 33 3a 34 34 3a 35 31 20 47 4d 54 0a 43 |1 13:44:51 GMT.C| 00000070 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 35 |ontent-Length: 5| 00000080 37 38 38 37 0a 0a 00 01 00 00 00 01 00 00 e2 15 |7887............| 00000090 12 22 0a 10 30 3a 31 64 3a 36 61 3a 61 39 3a 62 |."..0:1d:6a:a9:b| 000000a0 31 3a 65 32 12 0e 08 bc a6 a6 89 11 10 99 ee ec |1:e2............| 000000b0 eb 01 18 45 12 21 0a 0f 30 3a 32 35 3a 31 35 3a |...E.!..0:25:15:| 000000c0 34 61 3a 61 65 3a 34 12 0e 08 85 c3 a8 89 11 10 |4a:ae:4.........| 000000d0 9d c6 eb eb 01 18 3d 12 21 0a 0f 30 3a 31 34 3a |......=.!..0:14:| 000000e0 61 34 3a 35 65 3a 65 34 3a 37 12 0e 08 f6 c1 a8 |a4:5e:e4:7......| 000000f0 89 11 10 e3 a3 eb eb 01 18 5e 12 22 0a 10 30 3a |.........^."..0:| 00000100 31 65 3a 33 37 3a 61 63 3a 38 34 3a 39 61 12 0e |1e:37:ac:84:9a..| 00000110 08 c0 bf a4 89 11 10 d4 8e e5 eb 01 18 32 12 20 |.............2. | 00000120 0a 0e 30 3a 33 3a 63 39 3a 37 30 3a 63 35 3a 39 |..0:3:c9:70:c5:9| 00000130 12 0e 08 e4 a8 a4 89 11 10 f4 f2 e4 eb 01 18 32 |...............2| 00000140 12 21 0a 0f 30 3a 31 66 3a 39 66 3a 65 34 3a 35 |.!..0:1f:9f:e4:5| 00000150 31 3a 35 12 0e 08 cc 9f ac 89 11 10 b0 e8 f1 eb |1:5.............| 00000160 01 18 32 12 23 0a 11 34 36 3a 36 63 3a 39 34 3a |..2.#..46:6c:94:| ...
Here again, it’s encoded in Google “Protocol Buffers” format and is decoded this way :
2 {
1: "0:1d:6a:a9:b1:e2"
2 {
1: 4582904636
2: 494614297
3: 69
}
}
2 {
1: "0:25:15:4a:ae:4"
2 {
1: 4582941061
2: 494592797
3: 61
}
}
2 {
1: "0:14:a4:5e:e4:7"
2 {
1: 4582940918
2: 494588387
3: 94
}
2 {
1: "0:1e:37:ac:84:9a"
2 {
1: 4582875072
2: 494487380
3: 50
}
}
2 {
1: "0:3:c9:70:c5:9"
2 {
1: 4582872164
2: 494483828
3: 50
}
}
2 {
1: "0:1f:9f:e4:51:5"
2 {
1: 4583002060
2: 494695472
3: 50
}
}
…
So, for every WIFI hotspot known by Apple servers around my location, I get the corresponding location (latitude is the first number, longitude is the second) ; I don’t know exactly what’s the third number.
And, it’s the same kind of request/response for Cellular geolocation : a request is sent with cellular information (MCC, MNC, CellID, LAC) and the responses contains the list of cells around with corresponding latitude/longitude.
Once this information received, the Apple Maps application calculates the exact position of the device and then get the tiles needed to display the map with the location. Where does it get this tiles from ?
Here’s the request :
00000000 50 4f 53 54 20 68 74 74 70 3a 2f 2f 77 77 77 2e |POST http://www.| 00000010 67 6f 6f 67 6c 65 2e 63 6f 6d 2f 67 6c 6d 2f 6d |google.com/glm/m| 00000020 6d 61 70 20 48 54 54 50 2f 31 2e 31 0a 0a 50 4f |map HTTP/1.1..PO| 00000030 53 54 20 68 74 74 70 3a 2f 2f 77 77 77 2e 67 6f |ST http://www.go| 00000040 6f 67 6c 65 2e 63 6f 6d 2f 67 6c 6d 2f 6d 6d 61 |ogle.com/glm/mma| 00000050 70 20 48 54 54 50 2f 31 2e 31 0a 48 6f 73 74 3a |p HTTP/1.1.Host:| 00000060 20 77 77 77 2e 67 6f 6f 67 6c 65 2e 63 6f 6d 0a | www.google.com.| 00000070 55 73 65 72 2d 41 67 65 6e 74 3a 20 41 70 70 6c |User-Agent: Appl| 00000080 65 20 69 50 68 6f 6e 65 20 76 38 43 31 34 38 20 |e iPhone v8C148 | 00000090 4d 61 70 73 20 76 34 2e 32 2e 31 0a 41 63 63 65 |Maps v4.2.1.Acce| 000000a0 70 74 3a 20 2a 2f 2a 0a 41 63 63 65 70 74 2d 4c |pt: */*.Accept-L| 000000b0 61 6e 67 75 61 67 65 3a 20 66 72 2d 66 72 0a 41 |anguage: fr-fr.A| 000000c0 63 63 65 70 74 2d 45 6e 63 6f 64 69 6e 67 3a 20 |ccept-Encoding: | 000000d0 67 7a 69 70 2c 20 64 65 66 6c 61 74 65 0a 43 6f |gzip, deflate.Co| 000000e0 6e 74 65 6e 74 2d 54 79 70 65 3a 20 61 70 70 6c |ntent-Type: appl| 000000f0 69 63 61 74 69 6f 6e 2f 78 2d 77 77 77 2d 66 6f |ication/x-www-fo| 00000100 72 6d 2d 75 72 6c 65 6e 63 6f 64 65 64 0a 43 6f |rm-urlencoded.Co| 00000110 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 31 37 |ntent-Length: 17| 00000120 36 0a 0a 00 0e c0 b0 91 8b f6 07 30 fb 00 05 66 |6..........0...f| 00000130 72 5f 46 52 00 1d 63 6f 6d 2e 61 70 70 6c 65 2e |r_FR..com.apple.| 00000140 69 70 61 64 2d 63 6f 6d 2e 61 70 70 6c 65 2e 4d |ipad-com.apple.M| 00000150 61 70 73 00 0b 34 2e 32 2e 31 2e 38 43 31 34 38 |aps..4.2.1.8C148| 00000160 3e 00 00 00 0f 0a 03 34 31 37 10 01 20 00 a8 01 |>......417.. ...| 00000170 00 c0 01 02 1a 00 08 00 02 01 00 00 00 00 00 00 |................| 00000180 00 80 3f 02 00 00 41 c5 00 00 2d a0 10 02 00 00 |..?...A...-.....| 00000190 41 c5 00 00 2d a1 10 02 00 00 41 c5 00 00 2d 9f |A...-.....A...-.| 000001a0 10 02 00 00 41 c5 00 00 2d 9e 10 02 00 00 41 c5 |....A...-.....A.| 000001b0 00 00 2d a2 10 02 00 00 41 c5 00 00 2d a3 10 02 |..-.....A...-...| 000001c0 00 00 41 c5 00 00 2d 9d 10 02 00 00 41 c5 00 00 |..A...-.....A...| 000001d0 2d 9c 10 |-..|
As you can see, the map tiles are retrieved directly from Google servers using a POST request to http://www.google.com/glm/mmap – that’s an other clue showing that Apple uses Google technology to power its Maps application.
I couldn’t really decode the request but we can find 8 times the quite-same numbers :
- 02 00 00 41 c5 00 00 2d a0 10
- 02 00 00 41 c5 00 00 2d a1 10
- 02 00 00 41 c5 00 00 2d 9f 10
- 02 00 00 41 c5 00 00 2d 9e 10
- 02 00 00 41 c5 00 00 2d a2 10
- 02 00 00 41 c5 00 00 2d a3 10
- 02 00 00 41 c5 00 00 2d 9d 10
- 02 00 00 41 c5 00 00 2d 9c 10
It appears that this is the position of the different tiles that are downloaded.
This is the beginning of the response (as you understand, it’s quite long) :
00000000 50 4f 53 54 20 68 74 74 70 3a 2f 2f 77 77 77 2e |POST http://www.| 00000010 67 6f 6f 67 6c 65 2e 63 6f 6d 2f 67 6c 6d 2f 6d |google.com/glm/m| 00000020 6d 61 70 20 48 54 54 50 2f 31 2e 31 0a 0a 48 54 |map HTTP/1.1..HT| 00000030 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0a 43 6f |TP/1.1 200 OK.Co| 00000040 6e 74 65 6e 74 2d 54 79 70 65 3a 20 61 70 70 6c |ntent-Type: appl| 00000050 69 63 61 74 69 6f 6e 2f 62 69 6e 61 72 79 0a 43 |ication/binary.C| 00000060 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 34 |ontent-Length: 4| 00000070 33 30 38 35 0a 44 61 74 65 3a 20 57 65 64 2c 20 |3085.Date: Wed, | 00000080 30 32 20 46 65 62 20 32 30 31 31 20 31 33 3a 34 |02 Feb 2011 13:4| 00000090 34 3a 35 35 20 47 4d 54 0a 45 78 70 69 72 65 73 |4:55 GMT.Expires| 000000a0 3a 20 57 65 64 2c 20 30 32 20 46 65 62 20 32 30 |: Wed, 02 Feb 20| 000000b0 31 31 20 31 33 3a 34 34 3a 35 35 20 47 4d 54 0a |11 13:44:55 GMT.| 000000c0 43 61 63 68 65 2d 43 6f 6e 74 72 6f 6c 3a 20 70 |Cache-Control: p| 000000d0 72 69 76 61 74 65 2c 20 6d 61 78 2d 61 67 65 3d |rivate, max-age=| 000000e0 30 0a 58 2d 43 6f 6e 74 65 6e 74 2d 54 79 70 65 |0.X-Content-Type| 000000f0 2d 4f 70 74 69 6f 6e 73 3a 20 6e 6f 73 6e 69 66 |-Options: nosnif| 00000100 66 0a 58 2d 46 72 61 6d 65 2d 4f 70 74 69 6f 6e |f.X-Frame-Option| 00000110 73 3a 20 53 41 4d 45 4f 52 49 47 49 4e 0a 58 2d |s: SAMEORIGIN.X-| 00000120 58 53 53 2d 50 72 6f 74 65 63 74 69 6f 6e 3a 20 |XSS-Protection: | 00000130 31 3b 20 6d 6f 64 65 3d 62 6c 6f 63 6b 0a 53 65 |1; mode=block.Se| 00000140 72 76 65 72 3a 20 47 53 45 0a 0a 00 0e 3e 00 00 |rver: GSE....>..| 00000150 00 00 1a 00 18 00 00 08 02 00 00 41 c5 00 00 2d |...........A...-| 00000160 a0 10 1d bf 4c 54 49 50 0a 00 00 00 11 22 0f 0a |....LTIP....."..| 00000170 0a 54 65 6c 65 20 41 74 6c 61 73 18 db 0f 89 50 |.Tele Atlas....P| 00000180 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 |NG........IHDR..| 00000190 01 00 00 00 01 00 08 03 00 00 00 6b ac 58 54 00 |...........k.XT.| 000001a0 00 00 09 70 48 59 73 00 00 00 1c 00 00 00 1c 00 |...pHYs.........| 000001b0 0f 01 b9 8f 00 00 00 54 50 4c 54 45 eb e6 dc f2 |.......TPLTE....| 000001c0 ef e9 ff ff ff d1 d0 cd e0 d8 d0 ef eb e6 e0 e0 |................| 000001d0 e0 e6 e0 d5 dc d5 c9 bd bd bd d1 cd bd c9 c1 ad |................| 000001e0 f7 f7 f2 fb fb f7 d0 c5 b5 ad ad ad d8 d0 c1 3d |...............=| 000001f0 3d 3d 2d 2d 2d 7d 7d 7d 8d 8d 8d a1 a1 a1 cd c9 |==---}}}........| 00000200 c1 5d 5d 5d c5 b9 a9 c9 c1 b5 6d 6d 6d 4d 4d 4d |.]]]......mmmMMM| …
You can see in the response a ‘PNG’ header and we can find this header 8 times in the whole response – so this is the 8 tiles in PNG format that are sent to the iOS device.
To conclude :
- This test shows that Apple is much more ‘privacy-friendly’ with its network geolocation feature in the Maps application when compared to Google ones on Android : whereas Google Maps sends to Google servers identified location data (linked to your gmail account), the Apple Maps application only sends the mandatory information to do the network geolocation
- The Apple network geolocation service seems to heavily rely on Google technology (Google “protocol buffers” encoding, Google servers to retrieve map tiles) – we can wonder if the network geolocation databases are also shared with Google
- By the way the Apple network geolocation feature works (downloading subset of the network geolocation databases and probably caching the results on the device), we can assume that it’s more performant than Google one (where the device has to issue a request to Google for every network geolocation)
Dan.







