Jump to content
  • entries
  • comments
  • views

iOS programming - end of line confusion



One of the features of my iOS game is a level editor, so users can create their own levels. The plan is for users to create levels then submit them to me (via email). I will then take those levels and add them to the application bundle and update the app so everyone gets to play them.

The hard part turned out to be easy and the easy part turned out to be hard. Creating the email itself was easy - only a few lines of code. I could even easily create attachments, including the PNG of the level which my app already creates for the user created levels. The hard part turned out to be sending the level data as an attachment.

After much fussing around with various serialization standards (e.g. JSON, XML), I decided to KISS and use a simple key value format. Originally I used key=value<eol>, but I later changed it to key<tab>value<eol> in case someone put an = into their level title. The idea is to make the attachment transparent to avoid any concerns about collecting user data. The problem with this is the user could potentially change the file before sending it to me - making it unsolvable. (The game won't let you submit a level until you've successfully completed it.) So I needed to add some kind of checksum to the file to detect and discourage changes.

I decided to kill two birds with one program and code up a MacOS app (in Swift) which would read the file, verify the checksum, and update the SQLite database which would get included into the iOS app.

My first attempt was to use the hashValue property built into Swift. I figured even if it wasn't a full-blown cryptographic hash, it would be "good enough". Unfortunately, it turns out the hashValue isn't a true hash of the value, but instead is just the address of the object. (Which might be good enough for some purposes, but is far from being an actual hash.) So I went looking for a real hash function and learned Apple provides a library of crypto functions (including hashes). They are C functions, but so is SQLite.

Of course, that didn't work the first time. The function produced output, but the output didn't match - although the input looked the same. So I changed the iOS app to send a Bas64 version of the input as the checksum and had the MacOS app do the same thing. Bingo - the start of the input was the same, but it deviated along the way.

After more debug printing, I managed to identify the problem - somewhere, somehow, the end of lines in the KVP file were being changed from LF to CR+LF and the CRs weren't being stripped out of the input to the hash. Once I modified the MacOS app to remove the extra CRs the "checksum" matched and so did the hash value.


Recommended Comments

SMTP appears to use CR+LF for terminating the lines, possibly it's getting converted because of that if your attachment is just text. Maybe try to "zip" it before attaching so it's sent as a binary file?

Link to comment

Hi Darrell,


Maybe, but the input is from an attachment (with a kvp extension) which is marked as application/octet-stream. I haven't tried to access and decode the raw SMTP, but I that should keep it as a binary file from iOS to my Download directory. The actual contents are utf8 text, and I've successfully passed Chinese, Hebrew and Arabic characters and even emoji. It's just the EOL which is being changed. Not a big deal, just annoying.



Just downloaded and checked the file on my work laptop (Windows) and it's only LF. So it's either MacOS or the String from file initializer (bets on the latter).

Link to comment
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...