Table of Contents

Shortnote

The iOS camerarefresh package will hint to iOS to refresh the camera roll cache whenever new images are transferred to the iDevice. It does that by monitoring the camera roll directory and deleting the cache files that iOS maintains so that the Photos application will rebuild the cache when a new file is added.

Setup: Samba

The samba package is available from Cydia and already sets-up shares for the camera roll. The changes that need to be made would be to change the camera_readonly share to read-write so you can add pictures over the network.

The file that needs to be modified is /etc/smb.conf and you need to change the camera_readonly share to look like:

[camera]
path = /private/var/mobile/Media/DCIM/100APPLE
read only = no
browsable = yes

this will allow you to mount the camera share from Windows or OSX and add images. After making these changes, restart samba from the Preferences application.

Adding Images

Now you can mount the camera share and add images. However, the image file-names have to be changed to the following format:

IMG_XXXX.PNG

where XXXX is a number starting with 0001 and ending in 9999. In this case a PNG-type image was used, however iOS recognizes JPG images as well. As an example, you could have the following images in the camera share:

IMG_0001.PNG
IMG_0002.JPG
IMG_0003.JPG
IMG_0004.PNG
...

You have to make sure that the file-name format is followed, or else iOS will not recognize the new images you transfer. For example, if you add an image called wallpaper.png, iOS will not recognize it and you would need to rename it to something like IMG_0020.PNG.

Deep Notes

The camera refresh is based on a plist that monitors the /private/var/mobile/Media/DCIM/100APPLE share for new images:

org.grimore.camerarefresh.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>net.was.camerarefresh</string>
	<key>LowPriorityIO</key>
	<true/>
	<key>ProgramArguments</key>
	<array>
		<string>/usr/libexec/camera_refresh.sh</string>
	</array>
        <key>WatchPaths</key>
	<array>
		<string>/private/var/mobile/Media/DCIM/100APPLE</string>
	</array>
	<key>RunAtLoad</key>
	<true/>
</dict>
</plist>

when a new image is added, it runs the camera_refresh.sh script:

camera_refresh.sh
#!/bin/bash
# Copyright (C) Wizardry and Steamworks.
#
#  Licensed to Wizardry and Steamworks under
# the GPLv3 GNU License which can be found at:
#    http://www.gnu.org/licenses/gpl.html
#
 
# acquire lock
if mkdir /tmp/org.grimore.camerarefresh; then
  rm -rf /private/var/mobile/Media/PhotoData/{Photos.sqlite,PhotosAux.sqlite,MISC,Caches,Thumbnails}
  # release lock
  rm -rf /tmp/org.grimore.camerarefresh
fi

In order to not the script several times (for example, on multiple file transfers), we add a locking system by creating a directory at /tmp/org.grimore.camerarefresh. A second run of the script will not be possible because the directory will already exist. When the script has finished and the cache files and databases have been removed, the script unlocks and allows other runs by deleting the /tmp/org.grimore.camerarefresh directory.

The magic comes from launchd that uses the filesystem's internal routines to check whether the /private/var/mobile/Media/DCIM/100APPLE directory has changed and is largely efficient because this system does not add yet another third-party daemon in the background that would achieve the same effect. Because of this, the whole mechanism barely uses up any battery or processing power and the bash script will only run when new images are added.