Hallo allerseits,
da es ja die letzte Tage etwas Probleme mit einigen PHP Klassen beim Thema „Find my iPhone“ gab, hab ich mich auf die Suche gemacht und eine neue Klasse gefunden und mal ein paar Beispiele zusammengestellt
Link zum GitHub Repo: Neal/FindMyiPhone · GitHub
PHP CLASS:
<?php
/**
* FindMyiPhone - A PHP class for interacting with iCloud's Find My iPhone.
* Copyright (c) 2013 Neal <neal@ineal.me>
*/
class FindMyiPhone {
private $username;
private $password;
public $devices = array();
private $email_updates = true;
private $host = 'fmipmobile.icloud.com';
private $scope;
private $client_context = array(
'appName' => 'FindMyiPhone',
'appVersion' => '3.0',
'buildVersion' => '376',
'clientTimestamp' => 0,
'deviceUDID' => null,
'inactiveTime' => 1,
'osVersion' => '7.0.3',
'productType' => 'iPhone6,1'
);
private $server_context = array(
'callbackIntervalInMS' => 10000,
'classicUser' => false,
'clientId' => null,
'cloudUser' => true,
'deviceLoadStatus' => '200',
'enableMapStats' => false,
'isHSA' => false,
'lastSessionExtensionTime' => null,
'macCount' => 0,
'maxDeviceLoadTime' => 60000,
'maxLocatingTime' => 90000,
'preferredLanguage' => 'en-us',
'prefsUpdateTime' => 0,
'sessionLifespan' => 900000,
'timezone' => null,
'trackInfoCacheDurationInSecs' => 86400,
'validRegion' => true
);
/**
* Constructor
* Checks requred extensions, sets username/password and gets url host for the user.
* @param $username - iCloud Apple ID
* @param $password - iCloud Password
*/
public function __construct($username, $password) {
if (!extension_loaded('curl')) {
throw new FindMyiPhoneException('PHP extension cURL is not loaded.');
}
$this->username = $username;
$this->password = $password;
$this->init_client();
}
/**
* Set email updates
* If false, requests will request to not send email to the user. (doesn't work on all requests)
* True by default. (optional to set)
* $param $email_updates - bool
*/
public function set_email_updates($email_updates) {
$this->email_updates = (bool) $email_updates;
}
/**
* Init Client
*
*/
private function init_client() {
$post_data = json_encode(array(
'clientContext' => $this->client_context
));
$headers = $this->parse_curl_headers($this->make_request('initClient', $post_data, true));
$this->host = $headers['X-Apple-MMe-Host'];
$this->scope = $headers['X-Apple-MMe-Scope'];
$this->refresh_client();
}
/**
* Refresh Client
*
*/
public function refresh_client() {
$post_data = json_encode(array(
'clientContext' => $this->client_context,
'serverContext' => $this->server_context
));
foreach (json_decode($this->make_request('refreshClient', $post_data))->content as $id => $device) {
$this->devices[$id] = $device;
}
}
/**
* Play Sound
*
*/
public function play_sound($device_id, $subject = 'Find My iPhone Alert') {
if(!is_string($device_id)) throw new FindMyiPhoneException('Expected $device_id to be a string');
if(!is_string($subject)) throw new FindMyiPhoneException('Expected $subject to be a string');
$post_data = json_encode(array(
'clientContext' => $this->client_context,
'serverContext' => $this->server_context,
'device' => $device_id,
'subject' => $subject
));
return json_decode($this->make_request('playSound', $post_data))->content[0]->snd;
}
/**
* Send Message
*
*/
public function send_message($device_id, $text, $sound = false, $subject = 'Important Message') {
if(!is_string($device_id)) throw new FindMyiPhoneException('Expected $device_id to be a string');
if(!is_string($text)) throw new FindMyiPhoneException('Expected $text to be a string');
if(!is_bool($sound)) throw new FindMyiPhoneException('Expected $sound to be a bool');
if(!is_string($subject)) throw new FindMyiPhoneException('Expected $subject to be a string');
$post_data = json_encode(array(
'clientContext' => $this->client_context,
'serverContext' => $this->server_context,
'device' => $device_id,
'emailUpdates' => $this->email_updates,
'sound' => $sound,
'subject' => $subject,
'text' => $text,
'userText' => true
));
return json_decode($this->make_request('sendMessage', $post_data))->content[0]->msg;
}
/**
* Lock Device
*
*/
public function lost_device($device_id, $passcode, $owner_phone_number = '911', $sound = true, $text = 'This iPhone has been lost. Please call me.') {
if(!is_string($device_id)) throw new FindMyiPhoneException('Expected $device_id to be a string');
if(!is_string($passcode)) throw new FindMyiPhoneException('Expected $passcode to be a string');
if(strlen($passcode) !== 4) throw new FindMyiPhoneException('Expected $passcode to be 4 characters long');
if(!is_string($owner_phone_number)) throw new FindMyiPhoneException('Expected $owner_phone_number to be a string');
if(!is_bool($sound)) throw new FindMyiPhoneException('Expected $sound to be a bool');
if(!is_string($text)) throw new FindMyiPhoneException('Expected $text to be a string');
$post_data = json_encode(array(
'clientContext' => $this->client_context,
'serverContext' => $this->server_context,
'device' => $device_id,
'emailUpdates' => $this->email_updates,
'lostModeEnabled' => true,
'ownerNbr' => $owner_phone_number,
'passcode' => $passcode,
'sound' => $sound,
'text' => $text,
'trackingEnabled' => true,
'userText' => true
));
return json_decode($this->make_request('lostDevice', $post_data))->content[0]->lostDevice;
}
/**
* Notify When Found
*
*/
public function notify_when_found($device_id, $notify = true) {
if(!is_string($device_id)) throw new FindMyiPhoneException('Expected $device_id to be a string');
if(!is_string($notify)) throw new FindMyiPhoneException('Expected $notify to be a boolean');
$post_data = json_encode(array(
'clientContext' => $this->client_context,
'serverContext' => $this->server_context,
'device' => $device_id,
'lostModeEnabled' => $notify
));
return json_decode($this->make_request('saveLocFoundPref', $post_data))->content[0]->locFoundEnabled;
}
/**
* Lock and Message
*
*/
public function lock_and_message($device_id, $passcode, $text, $sound = true, $title = 'Find My iPhone Alert') {
if(!is_string($device_id)) throw new FindMyiPhoneException('Expected $device_id to be a string');
if(!is_string($passcode)) throw new FindMyiPhoneException('Expected $passcode to be a string');
if(strlen($passcode) !== 4) throw new FindMyiPhoneException('Expected $passcode to be 4 characters long');
if(!is_string($text)) throw new FindMyiPhoneException('Expected $text to be a string');
if(!is_bool($sound)) throw new FindMyiPhoneException('Expected $sound to be a bool');
if(!is_string($title)) throw new FindMyiPhoneException('Expected $title to be a string');
$post_data = json_encode(array(
'clientContext' => $this->client_context,
'serverContext' => $this->server_context,
'device' => $device_id,
'emailUpdates' => $this->email_updates,
'passcode' => $passcode,
'sound' => $sound,
'text' => $text,
'title' => $title,
'userText' => true
));
return json_decode($this->make_request('lockAndMessage', $post_data))->content[0]->remoteLock;
}
/**
* Remote Lock
*
*/
public function remote_lock($device_id, $passcode) {
if(!is_string($device_id)) throw new FindMyiPhoneException('Expected $device_id to be a string');
if(!is_string($passcode)) throw new FindMyiPhoneException('Expected $passcode to be a string');
if(strlen($passcode) !== 4) throw new FindMyiPhoneException('Expected $passcode to be 4 characters long');
$post_data = json_encode(array(
'clientContext' => $this->client_context,
'serverContext' => $this->server_context,
'device' => $device_id,
'emailUpdates' => $this->email_updates,
'passcode' => $passcode
));
return json_decode($this->make_request('remoteLock', $post_data))->content[0]->remoteLock;
}
/**
* Remote Wipe
*
*/
public function remote_wipe($device_id, $passcode, $text) {
if(!is_string($device_id)) throw new FindMyiPhoneException('Expected $device_id to be a string');
if(!is_string($passcode)) throw new FindMyiPhoneException('Expected $passcode to be a string');
if(strlen($passcode) !== 4) throw new FindMyiPhoneException('Expected $passcode to be 4 characters long');
if(!is_string($text)) throw new FindMyiPhoneException('Expected $text to be a string');
$post_data = json_encode(array(
'clientContext' => $this->client_context,
'serverContext' => $this->server_context,
'device' => $device_id,
'passcode' => $passcode,
'text' => $text,
'emailUpdates' => $this->email_updates
));
return json_decode($this->make_request('remoteWipe', $post_data))->content[0]->remoteWipe;
}
/**
* Locate Device
*
*/
public function locate_device($device, $timeout = 120) {
if(!is_integer($device)) throw new FindMyiPhoneException('Expected $device to be an integer');
if(!isset($this->devices[$device])) $this->refresh_client();
$start = time();
while (!$this->devices[$device]->location->locationFinished) {
if ((time() - $start) > intval($timeout)) {
throw new FindMyiPhoneException('Failed to locate device! Request timed out.');
}
sleep(5);
$this->refresh_client();
}
return $this->devices[$device]->location;
}
/**
* Make request to the Find My iPhone server.
* @param $method - the method
* @param $post_data - the POST data
* @param $return_headers - also return headers when true
* @param $headers - optional headers to send
* @return HTTP response
*/
private function make_request($method, $post_data, $return_headers = false, $headers = array()) {
if(!is_string($method)) throw new FindMyiPhoneException('Expected $method to be a string');
if(!$this->is_json($post_data)) throw new FindMyiPhoneException('Expected $post_data to be json');
if(!is_array($headers)) throw new FindMyiPhoneException('Expected $headers to be an array');
if(!is_bool($return_headers)) throw new FindMyiPhoneException('Expected $return_headers to be a bool');
if(!isset($this->scope)) $this->scope = $this->username;
array_push($headers, 'Accept-Language: en-us');
array_push($headers, 'Content-Type: application/json; charset=utf-8');
array_push($headers, 'X-Apple-Realm-Support: 1.0');
array_push($headers, 'X-Apple-Find-Api-Ver: 3.0');
array_push($headers, 'X-Apple-Authscheme: UserIdGuest');
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_TIMEOUT => 9,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_AUTOREFERER => true,
CURLOPT_VERBOSE => false,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $post_data,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_HEADER => $return_headers,
CURLOPT_URL => sprintf("https://%s/fmipservice/device/%s/%s", $this->host, $this->scope, $method),
CURLOPT_USERPWD => $this->username . ':' . $this->password,
CURLOPT_USERAGENT => 'FindMyiPhone/376 CFNetwork/672.0.8 Darwin/14.0.0'
));
$http_result = curl_exec($curl);
curl_close($curl);
return $http_result;
}
/**
* Parse cURL headers
* @param $response - cURL response including the headers
* @return array of headers
*/
private function parse_curl_headers($response) {
$headers = array();
foreach (explode("
", substr($response, 0, strpos($response, "
"))) as $i => $line) {
if ($i === 0) {
$headers['http_code'] = $line;
} else {
list($key, $value) = explode(': ', $line);
$headers[$key] = $value;
}
}
return $headers;
}
/**
* Finds whether a variable is json.
*/
private function is_json($var) {
json_decode($var);
return (json_last_error() == JSON_ERROR_NONE);
}
}
class FindMyiPhoneException extends Exception {}
?>
…Skript erstellen mit obigem Inhalt und Skript umbenennen in „findmyiphone.ips.php“
Beispiel-Skript zum Senden einer Nachricht:
<?
require ('findmyiphone.ips.php');
$FindMyiPhone = new FindMyiPhone('BENUTZERNAME', 'PASSWORT'); // iCloud Benutzer/Passwort eingeben
// print_r($FindMyiPhone->devices); // Devices mit allen Infos auflisten
$device_id = $FindMyiPhone->devices[1]->id;
$text = 'Ich bin eine Nachricht.';
echo 'Sende Nachricht... '."
";
echo ($FindMyiPhone->send_message($device_id, $text, false, 'IP-Symcon')->statusCode == 200) ? '...gesendet!' : '...Fehler!';
echo PHP_EOL;
?>
Beispiel-Skript zum Abspielen eines „Alarm-Ton“:
<?
require ('findmyiphone.ips.php');
$FindMyiPhone = new FindMyiPhone('BENUTZERNAME', 'PASSWORT'); // iCloud Benutzer/Passwort eingeben
// print_r($FindMyiPhone->devices); // Devices mit allen Infos auflisten
$device_id = $FindMyiPhone->devices[1]->id;
$text = 'IP-Symcon';
echo 'Sound abspielen... '."
";
echo ($FindMyiPhone->play_sound($device_id, $text)->statusCode == 200) ? '...wird abgespielt!' : '...Fehler!';
echo PHP_EOL;
?>
Beispiel-Skript zum Auslesen des Standortes:
<?
require ('findmyiphone.ips.php');
$FindMyiPhone = new FindMyiPhone('BENUTZERNAME', 'PASSWORT'); // iCloud Benutzer/Passwort eingeben
//print_r($FindMyiPhone->devices); // Devices mit allen Infos auflisten
$longitude = $FindMyiPhone->devices[1]->location->longitude;
$latitude = $FindMyiPhone->devices[1]->location->latitude;
echo "Longitude = ".$longitude;
echo "Latitude = ".$latitude;
?>
Alle (in meinen Augen) sinnvollen Infos in eine Variable schreiben lassen:
<?
require ('findmyiphone.ips.php');
$FindMyiPhone = new FindMyiPhone('BENUTZERNAME', 'PASSWORT'); // iCloud Benutzer/Passwort eingeben
//print_r($FindMyiPhone->devices); // Alle Devices mit allen Infos auflisten
$device_id = $FindMyiPhone->devices[1]->id; // durch "devices[1]" mein iPhone ausgewählt
// Location Infos
$location_timeStamp = $FindMyiPhone->devices[1]->location->timeStamp;
$location_positionType = $FindMyiPhone->devices[1]->location->positionType;
$location_horizontalAccuracy = $FindMyiPhone->devices[1]->location->horizontalAccuracy;
$location_longitude = $FindMyiPhone->devices[1]->location->longitude;
$location_latitude = $FindMyiPhone->devices[1]->location->latitude;
// Device Infos
$deviceModel = $FindMyiPhone->devices[1]->deviceModel;
$activationLocked = $FindMyiPhone->devices[1]->activationLocked;
$rawDeviceModel = $FindMyiPhone->devices[1]->rawDeviceModel;
$modelDisplayName = $FindMyiPhone->devices[1]->modelDisplayName;
$deviceDisplayName = $FindMyiPhone->devices[1]->deviceDisplayName;
$locationCapable = $FindMyiPhone->devices[1]->locationCapable;
$batteryLevel = $FindMyiPhone->devices[1]->batteryLevel;
$name = $FindMyiPhone->devices[1]->name;
$passcodeLength = $FindMyiPhone->devices[1]->passcodeLength;
$deviceColor = $FindMyiPhone->devices[1]->deviceColor;
$batteryStatus = $FindMyiPhone->devices[1]->batteryStatus;
$deviceStatus = $FindMyiPhone->devices[1]->deviceStatus;
?>
Liste aller verfügbaren Infos pro Device:
stdClass Object
(
[canWipeAfterLock] => 1
[remoteWipe] =>
[locFoundEnabled] =>
[location] => stdClass Object
(
[timeStamp] => 1420458331310
[locationType] =>
[positionType] => Cell
[horizontalAccuracy] => ******
[locationFinished] =>
[isInaccurate] =>
[longitude] => ***********
[latitude] => *********
[isOld] =>
)
[deviceModel] => iphone6-*******
[remoteLock] =>
[activationLocked] => 1
[locationEnabled] => 1
[rawDeviceModel] => iPhone7,2
[modelDisplayName] => iPhone
[lostModeCapable] => 1
[id] => ********
[deviceDisplayName] => iPhone 6
[darkWake] =>
[locationCapable] => 1
[batteryLevel] => 0.6
[maxMsgChar] => 160
[name] => iPhone6Chris
[features] => stdClass Object
(
[CLT] =>
[CWP] =>
[WMG] => 1
[XRM] =>
[CLK] =>
[SND] => 1
[LST] => 1
[KEY] =>
[WIP] => 1
[LOC] => 1
[LLC] =>
[MSG] => 1
[LMG] =>
[LCK] => 1
[REM] =>
[SVP] =>
[TEU] => 1
[LKL] =>
[LKM] =>
[PIN] =>
[KPD] =>
)
[deviceClass] => iPhone
[wipeInProgress] =>
[fmlyShare] =>
[passcodeLength] => *****
[mesg] =>
[isMac] =>
[snd] => stdClass Object
(
[statusCode] => 200
[createTimestamp] => 1420456410736
)
[isLocating] => 1
[deviceColor] => 3b3b3c-b4b5b9
[trackingInfo] =>
[batteryStatus] => NotCharging
[deviceStatus] => 200
[wipedTimestamp] =>
[lockedTimestamp] =>
[msg] => stdClass Object
(
[statusCode] => 200
[createTimestamp] => 1420456410736
[userText] =>
[playSound] => 1
)
[lostTimestamp] =>
[lostModeEnabled] =>
[thisDevice] =>
[lostDevice] =>
[prsId] =>
)
Viel Spaß und Grüße,
Chris