Meine wohl häufig genutzte iPhone App ist die Messaging App, welche ich jeden Tag mehrmals nutze. Es gibt glaube ich keine andere App auf dem iPhone, welche ich bisher so oft benutzt habe. Seit dem Fimwareupdate 3.0 kann die Messaging App auch MMS, vorher hies die App ganz simpel SMS und konnte “nur” SMS verschicken und empfangen. Die Messaging App die App, welche seit der Firmware 1.0 am meisten Veränderungen durchlaufen hat. Doch was steckt hinter der Messaging App und wie werden die SMS und MMS auf dem iPhone abgespeichert und organisiert?
Die MMS und SMS werden auf dem iPhone direkt in eine SQL Lite Datebank gespeichert und werden beim Anzeigen aus der Datenbank ausgelesen. Bei dem Backup via iTunes wird die Datenbank direkt auf den Rechner übertragen und kann so direkt mit einem SQL Lite Client ausgelesen werden. Dazu sind ein paar SQL Statements nötig um an die gespeicherten Daten heranzukommen.
Aber wo ist das Backup vom iTunes abgespeichert? Wie kann ich die Nachrichten auslesen? Wie ist die Datebank aufgebaut und auf welchem System läuft diese? Alle diese Fragen werden mit diesem Beitrag beantwortet.
Speicherort der iTunes Backups
Das von iTunes erstellte Backup wird je nach Betriebssystem, also Mac oder Windows, unter einem anderen Pfad abgespeichert. Hier nun eine kleine Übersicht über die Speicherpfade der verschiedenen Betriebssysteme:
Windows XP: C:\Documents and Settings\[your username]\Application Data\Apple Computer\MobileSync\Backup\[id]\
Windows Vista/Windows 7: C:\Users\[your username]\AppData\Roaming\[your username]\Application Data\Apple Computer\MobileSync\Backup\[id]\
Mac OS X: User>Library>Application Support>Mobile Sync>Backup>[some id]
Der Ordner Applcation Data unter Windows ist ein versteckter Ordner und muss zuerst angezeigt werden. Dies geschieht über den Explorer, Extras, Ordneroptionen.
Offnet man den Backup Ordner, sieht man zuerst einfach einen haufen Dateien, die einen nichts sagenden Dateinamen besitzen. Doch hier befindet sich die SQL Lite Datebank, welche unsere SMS beinhalten, bei dem MMS wird der Text gespeichert und den Pfad zu dem Bild, wenn das MMS ein Bild oder andere Medien enthält.

Wo sind die SMS und MMS Daten gespeichert?
Der Dateiname heisst 3d0d7e5fb2ce288813306e4d4636395e047a3d28.mddata. Wenn man diese jedoch mit einem Texteditor öffnet, wird man zwar Text erkennen können, jedoch unstrukturiert und völlig durcheinander. Daher ist es nötig, diese mit einem SQL Lite Management Tool zu öffnen, ich habe für diesen Beitrag das Firefox Plugin SQL Light Manager benutzt. Es bietet alles, um die Daten auszulesen und anzeigen zu lassen. Auf der SQL Lite Homepage gibt es noch eine sehr ausführliche Liste mit anderen Management Tools und da ist sicherlich für jeden was dabei.
In welcher Form sind die SMS und MMS Daten abgespeichert?
Um die Daten zu speichern wird SQL Lite in der Version 3 verwendet. Das ermöglicht ein einfaches auslesen der Inhalte via SQL Statements (Befehle). SQL steht für Structured Query Language und ist eine standartisierte Sprache um Daten aus einer Datenbank auszulesen.
Wie sieht der Aufbau der SQL Lite Datenbank aus?
Die Datenbank besteht aus 6 Tabellen:
Die Tabelle _SqliteDatabaseProperties ist Systemtabelle, welche für SQL Lite notwendig ist und alle Konfigurationen des SQL Lite Server beinhalten.
Zur schnelleren Abfrage wia SQL sind auch Indexe vorhanden:
Die Indexe im Detail:
hash_index: CREATE INDEX hash_index ON msg_group(hash) message_flags_index: CREATE INDEX message_flags_index ON message(flags) message_group_index: CREATE INDEX message_group_index ON message(group_id, ROWID) message_groupid_read_index: CREATE INDEX message_groupid_read_index ON message(group_id, read) pieces_message_index: CREATE INDEX pieces_message_index ON msg_pieces(message_id)
Ebenfalls sind 7 Triggers sind vorhanden:
Trigger, auch Datenbanktrigger gennant werden zur Datenintegrität (Richtigkeit der Daten) eingesetzt. Im Detail werden Daten geprüft, welche gelöscht, geändert oder eingefügt werden.
Die Trigger im Detail:
delete_message:
CREATE TRIGGER delete_message AFTER DELETE ON message WHEN NOT read(old.flags) BEGIN UPDATE msg_group SET unread_count = (SELECT unread_count FROM msg_group WHERE ROWID = old.group_id) - 1 WHERE ROWID = old.group_id; END
delete_newest_message:
CREATE TRIGGER delete_newest_message AFTER DELETE ON message WHEN old.ROWID = (SELECT newest_message FROM msg_group WHERE ROWID = old.group_id) BEGIN UPDATE msg_group SET newest_message = (SELECT ROWID FROM message WHERE group_id = old.group_id AND ROWID = (SELECT max(ROWID) FROM message WHERE group_id = old.group_id)) WHERE ROWID = old.group_id; END
delete_pieces:
CREATE TRIGGER delete_pieces AFTER DELETE ON message BEGIN DELETE from msg_pieces where old.ROWID == msg_pieces.message_id; END
insert_newest_message:
CREATE TRIGGER insert_newest_message AFTER INSERT ON message WHEN new.ROWID >= IFNULL((SELECT MAX(ROWID) FROM message WHERE message.group_id = new.group_id), 0) BEGIN UPDATE msg_group SET newest_message = new.ROWID WHERE ROWID = new.group_id; END
insert_unread_message:
CREATE TRIGGER insert_unread_message AFTER INSERT ON message WHEN NOT read(new.flags) BEGIN UPDATE msg_group SET unread_count = (SELECT unread_count FROM msg_group WHERE ROWID = new.group_id) + 1 WHERE ROWID = new.group_id; END
mark_message_read:
CREATE TRIGGER mark_message_read AFTER UPDATE ON message WHEN NOT read(old.flags) AND read(new.flags) BEGIN UPDATE msg_group SET unread_count = (SELECT unread_count FROM msg_group WHERE ROWID = new.group_id) - 1 WHERE ROWID = new.group_id; END
mark_message_unread: CREATE TRIGGER mark_message_unread AFTER UPDATE ON message WHEN read(old.flags) AND NOT read(new.flags) BEGIN UPDATE msg_group SET unread_count = (SELECT unread_count FROM msg_group WHERE ROWID = new.group_id) + 1 WHERE ROWID = new.group_id; END
Das Datenbakschema:

Wie man sieht, ist die Datebank nicht all zu gross und leicht überschaubar. Die Felder sind teilweise selbsterklährend.
Nachfolgend werden die wichtigsten Tabellen etwas genauer erklärt:
Die Tabelle message
Wirklich interessant ist die Tabelle message. Alle anderen dienen teilweise nur zur Info oder für das Management der Nachrichten direkt auf dem iPhone.
Der Inhalt der Tabelle message kann so aussehen:
Es werden Daten wie Handynummer (adress), Datum (date), Text (text), Gruppe (group_id (jede Handynummer hat eine Group ID)) und ob die Nachricht gelesen wurde (read).
Um eine Konversation mit einer bestimmten Person (Handynummer) anzuzeigen, muss folgendes SQL Statement eingegeben werden:
SSELECT address, date, text FROM message WHERE group_id = 11 ORDER BY date
Mit dem Query werden die Spalten adress, date und text in der Tabelle message herausgesucht, welche die group_id 11 haben und nach Datum sortiert. So kann man eine ganze Konversation z.B. als Textdatei auf den Rechner speichern.
Die Tabelle group_member
In der Tabelle group_member werden alle Handynummern aufgeführt, wo SMS/MMS hingeschickt hat oder erhalten hat. Jede Handynummer hat group_id. Die group_id kennen wir ja schon von der Tabelle message. Streng genommen sind es redundante Daten, da die Handynummer in der Tabelle message schon in der Spalte adress vorhanden ist. Somit ist die Tabelle group_member eine Referenztabelle.
Die Tabelle msg_pieces
In der Tabelle msg_pieces werden alle Teile einer MMS Nachricht aufgeführt inkl. Inhalt, also Bilder oder Text. In einer MMS Nchricht können mehrere Bilder oder Text enthalten. Alle Teile einer Nachricht haben die gleiche message_id. So kann man mit einem einfachen SQL Statement alle Teile einer MMS Nachricht anzeigen lassen:
SELECT * FROM msg_pieces WHERE message_id = 5392
Hiermit werden alle Teile der MMS Nachricht mit der message_id 5392 angezeigt. Die Ausgabe sieht dann so aus:
Wie man sieht, besteht die MMS Nachricht aus einem Bild (jpg) einem Text (smil.txt) und einer Application, welche die Textdatei anzeigt. Diese ist in jeder MMS Nachricht vorhanden, also lässt sich sagen, das alle Zeilen mit der gleichen message_id gehören zu einer Nachricht.
So, das war der Überblick über die SMS Datenbank auf dem iPhone. Feedback und Anregungen sind wie immer, herzlich willkommen.
Auch lesenswert:
- [HowTo] Mails archivieren unter Mac Vor kurzem habe ich ein HowTo veröffentlicht, wie man unter Windows seine Mails ganz einfach archivieren kann. Auf diversen Kanälen, wie Facebook und Twitter kamen fragen, wie man dies unter...
- [iPhone] Endlich Perfekt: Mit 2Do Aufgaben verwalten (Update) Seit einiger Zeit habe ich die App 2Do im App Store gekauft mit der Absicht, meine Aufgaben zu synchroniseren, zum Einten mit meinem Mac und mit meinem Windows Rechner im...
- [HowTo] iPhone Firmware 3.0 MMS und Tethering Funktion freischalten Wer heute auf Facebook und Twitter meine Statusmeldungen mitverfolgt hat, der weis, das ich heute die Firmware 3.0 beta 3 auf mein iPhone geladen habe. Das Update ging ohne grössere...
- Offizieller Workarround für iTunes 8 und BSOD unter Windows Vista Die neue Version von iTunes hat nicht nur Freunde gemacht, so beschweren sich viele Windows Vista Benutzer, das wenn Sie den iPod oder das iPhone an den PC hängen, sich...
- Angeblich bereits 34’200 iPhones in der Schweiz Laut einem Bericht von heute sollen in der Schweiz bereits 34’200 iPhones im Umlauf sein. Ende Februar waren 5200 iPhones bereits auf dem Swisscom Netz eingebucht und rund einen Monat...








{ 7 comments… read them below or add one }
[Doku] SMS/MMS Datenbank des iPhones: Meine wohl häufig genutzte iPhone App ist die Messaging App, welche ich jede… http://bit.ly/b1D7ja
Super Artikel.
weisst du zufällig auch wie man die Db vom Mac aus auslesen kann ohne Sql Browser.
Würde gern vom lokalen Apache Server auf
die SMS.db des Iphone zugreifen.
Iphone ist per AFP mit dem Mac verbunden.
Funktioniert bisher nur wenn ich die Sms.db auf den Mac kopiere.
Ideen willkommen.
Gruss Sascha
schau mal unter dem link, welcher ich im beitrag geschrieben habe, dort hat es verschiedene clients, auch für den mac, welche lokal laufen und ohne browser. ich selbst habe aber diese nicht getestet.
Guter Beitrag, doch muss ich mich erst einmal in aller Ruhe einlesen, denn auf den ersten Blick wirkt das ganze doch etwas unübersichtlich, doch in bin mir sicher, dass auch ich bald von deinen Erklärungen profitieren kann. Danke schon mal
Wer diesen komplierten Vorgang etwas einfacher haben möchte, incl. einer ‘schicken’ Darstellung seiner Datenbanken, der sollte sich mal ‘iTwin’ von meiner Webseite ansehen. ( http://www.i-twin.de/ ) Hat schon so manchem geholfen … MfG.
Vielen Dank für den Beitrag!!!

Dadruch sind nun einige Fragen geklärt!
Allerdings bin ich mit meinem Versuch, eine SMS in die Datenbank hinzuzufügen, doch keinen wesentlichen Schritt weiter.
Hat jemand einen Tip für mich, wie ich das bewerkstelligen kann?
Denn ein einfaches INSERT funktioniert auf Grund der Trigger leider nicht.
Was muss ich beachten, damit die Trigger mitspielen?
Habe schon gelesen, dass einige die Trigger einfach deaktiviert haben, aber andererseits wichtige Verknüpfungen dann verloren gehen und die DB damit zumindest fürs iPhone zerschossen ist…
Hoffe es hat jemand eine gute Idee
Danke schonmal!
Gruß
Hallo nochmal!
Also ich korrigiere meine Aussage mit den Triggern noch mal:
Es klappt doch! Man mus nur die richtige Software haben, dann ist alles kein Problem!
Trotzdem vielen Dank für das Tutorial! Hat mir sehr geholfen!
Gruß
{ 1 trackback }