Escaping the sandbox in iOS
A post born of pain. It just so happens that right now I am poking at someone else’s project that is designed to run on jailbroken iPhones. And not just run on them — it needs access outside the sandbox.
As everyone knows, all apps in iOS run inside a sandbox and cannot go outside it. All App Store apps are installed into /var/mobile/Applications/ (apps installed onto an iPhone from Xcode go there as well), where a separate folder with an unreadable name is created for each app. You cannot go outside that folder. Not for reading and certainly not for writing.
This, for example, is the folder of Google’s Ingress game.
And this is the iOS Calculator app, for example, living in /Applications.
If we want, for example, to read the phone’s SMS messages from inside an app, we need to read the file /var/mobile/Library/SMS/sms.db — it is a regular SQLite database with no encryption or protection. You can download it from a jailbroken phone and open it with any tool that knows how to open SQLite files, look at all SMS messages, and even hammer it with sql queries for search and other tasks.
Here, for example, is the file with all iPhone SMS messages.
So, there is no access to that file from the sandbox. And Jailbreak does not solve that. It gives full access to the file system, but only if you are working outside the sandbox.
For an app to work outside the sandbox, it has to be moved from /var/mobile/Applications/ to the /Applications directory. Then the app will live in the system apps folder, have access to the file system on a jailbroken device, not be removable from the phone by holding a finger on its icon, and so on.
And that is where the pain starts: Xcode simply cannot install the app there; it can install only into the sandbox. You can do it by hand — connect to the phone and move it with something like iFunBox — but that is a huge pain every single time. The worst part is that you lose the convenience of debugging. You cannot run the app on the device from Xcode and calmly watch the console to see what your app is printing and whether it is working.
No tweaks from Cydia that supposedly give apps file-system access even from inside the sandbox had any effect. At least not for me on iOS 7.1.2. They say that even if you run the app as root but still inside the sandbox, it still will not get permission to read system directories. Although it feels like this used to work before, but jailbreaks were different back then too.
That is the hell I am in. In the near future I am going to try some scripts I found online to automate moving the app around inside the iPhone after the build via SSH while also capturing syslog. I also want to write up what I have dug out inside the iPhone in terms of “where everything is stored”, but later, once this hell is over :)
node-couchdb-mover

A few days ago I wrote my first Node.js tool. I wrote it only partly for myself, because for me it is not very relevant yet, but for some people it very much is.
The tool is for CouchDB. Since CouchDB keeps document revisions after changes and deletions and does not always clean them up, a database can grow like crazy. For example, for the guys who need this tool right now, something that should weigh 6 GB weighs 50-60. Maybe they started something somewhere or messed something up, changed and wrote a ton of stuff into the database, and that blew up its size. So, overall, it is easier to just create a new clean database and move all live documents there.
The tool simply takes all documents from 1 database in CouchDB and puts them into another one. For now it works rather crudely: it grabs all documents in one shot and then inserts them into the database one by one. For databases with a relatively small number of documents it works fine, but if there are something like 80 thousand documents, fetching them on my computer took about 4-5 minutes. So I will rework it soon so that it pulls documents in batches and writes them to the database sequentially instead of asynchronously.
But it is already usable. You can embed the tool into your own Node.js project, for example.
In the console:
npm install node-couchdb-mover
In code:
var mover = require('node-couchdb-mover');
mover.moveDocuments('dbName1', 'dbName2');
It can also be used directly from the console:
npm install -g node-couchdb-mover
couchdb-mover --from=dbName1 --to=dbName2
And, as expected, here are the sources on GitHub and the package on npmjs.org.
How to tell whether a display is Retina or not?
My blog gets a lot of search-engine traffic for queries like “How to detect a Retina display”. People land on my article about Objective-C, but they are clearly not looking for code :) So I ended up making a page like this one: you just open it in the browser on your device. If it is Retina, the result is green, like in the screenshot above. If it is not Retina, it is red, like in the screenshot below.
It works for iOS devices (iPhone, iPad, iPod) and Macs with a Retina display. On screens with a high pixel density it also says Retina :)
Page URL: https://arm1.ru/retina/
Linode client for iPhone
I have been using Linode.com hosting services for several years now. That is where I keep my VPS with sites / projects and for various personal purposes.
They have an API, and as far as I understand, they built an iPhone client on top of it.
The client looks like it was just reskinned.
Cheat sheet for setting up nginx+php-fpm from Homebrew
If after configuring nginx and php-fpm to work through php5-fpm.sock, Nginx throws a 502 bad gateway error and the log contains something like this:
*20 connect() to unix:/usr/local/var/run/php5-fpm.sock failed (2: No such file or directory) while connecting to upstream
Then the permissions problem can be fixed like this:
cd /usr/local/var/run
sudo chmod 666 php5-fpm.sock
If that helped, then in /usr/local/etc/php/5.5/php-fpm.conf you should also uncomment this line:
listen.mode = 0666
Writing a Yandex.Metrica Client for iPhone

A copy of my article from Habr
iMetrik 1.1 Update
Today the iMetrik update was released. The main additions are the Visitors tab with reports by gender, age, and geography, and the Goals tab, which contains all the same reports but for goals and with additional parameters such as goal achievement, conversion, and more.
Also fixed a couple of issues.