RecentChanges 2015-04-18 XML TXT

Latest weblog entries

2015-03-28 SSL security

An excellent article on SSL security, which tells you how to disable the RC4 cipher:

2015-03-13 Connecting to Oodrive via FTPS on OS X

For a client, I have to save files to Oodrive. They offer several methods for uploading, one of them being FTPS, i.e. FTP-over-SSL. It turns out it's quite a hassle when you use OS X.

Taking the following steps allowed me to connect.

First install Homebrew as usual, if you haven't yet installed it. Then edit the lftp recipe:

  $ brew edit lftp

Comment out the line that says "--with-openssl" and add a new line saying


Then install this recipe as follows:

  $ brew install --build-from-source lftp

See if you were successful:

  $ lftp -v
  Libraries used: Readline 6.3, Expat 2.0.1, GnuTLS 3.3.13, libiconv 1.11, zlib 1.2.5

Note the final line, where it should say "GnuTLS".

Now add the appropriate settings; create the .lftprc in your home directory, and paste the following lines (courtesy of the Reliable Penguin blog):

  set ftps:initial-prot ""
  set ftp:ssl-force true
  set ftp:ssl-protect-data true

Then, create the .lftp directory and create a file named "bookmarks" with the
following line:

  oodrive ftps://

To test the result, start lftp on the commandline and type "open oodrive",
then type "ls".

If you see the error "Fatal error: Certificate verification: Not trusted", you may want to add the following line to the .lftp settings file:

  set ssl:verify-certificate no

2015-02-06 Swift enum raw values as an array

Here's a quick example of using Swift's map() function. Here it's used to put the raw values of an enum into an array. Paste this into a playground to see the result.

	import Cocoa
	enum ContentType : Int {
		case Unknown = 0
		case PAS = 1
		case PASGENERIC = 2
		case PASROUTE = 3
		case PASBUNDLE = 4
		case TOPIC = 5
		case NEWS = 6
	let contentTypeArray = [ContentType.PAS, ContentType.PASROUTE, ContentType.TOPIC]
	let intArray ={type in type.rawValue})

Even shorter:

	let intArray ={$0.rawValue})

How it looks in a playground:

swift enum raw values as array playground.png

2015-02-05 Swift example of a batch update in Core Data

Here's a Swift example of doing a batch update in Core Data:

	let updateRequest = NSBatchUpdateRequest("some_entity_name")
	let predicateIsRead = NSPredicate(format: "isRead = %@", NSNumber(bool: true))
	updateRequest.predicate = predicateIsRead
	updateRequest.propertiesToUpdate = [
		ContentItemAttributes.isRead.rawValue: NSNumber(bool: false)
	updateRequest.resultType = NSBatchUpdateRequestResultType.UpdatedObjectsCountResultType
	var error: NSError?
	let updateResult = objectContext.executeRequest(updateRequest, error: &error) as NSBatchUpdateResult?
	if let result = updateResult {
		let count = result.result as Int
		println("Updated \(count) rows")
	} else {
		println("Error during batch update: \(error?.localizedDescription)")

Note that you'll need to update the objects in memory. The above code just prints the row count. If you have stuff displayed in the user interface, use this answer on Stack Overflow to adjust the above code.

2015-02-01 Layout of a tableviewcell depending upon device orientation

Last week, a refresh of the design of my client's app called for a layout that changed depending on the device orientation. We're using AutoLayout and didn't want to use any deprecated methods.

Problem was that it called for layout changes within a UITableViewCell. I thought of a way to do this with AutoLayout but the constraints would become quite complex. Instead, I took the following approach:

  • Create a custom UITableViewCell by subclassing it
  • To this subclass, add outlets for the constraints that you want to influence
  • In the view controller, detect whether we're in portrait or landscape, then update the constraints of the cells using the IBOutlet properties

Thus the UITableViewCell subclass looks as follows:

	class CustomTableCell : UITableViewCell {
		@IBOutlet weak var dateLabel: UILabel!
		@IBOutlet weak var nameLabel: UILabel!
		@IBOutlet weak var trailingConstraint: NSLayoutConstraint!

Problem is: where can you set properties all the currently visible cells? The easiest way I could come up with, is in the cellForRowAtIndexPath() function. The view controller class has the following property:

	var size: CGSize = CGSizeZero

The viewWillTransitionToSize() function stores the new screen size and asks the UITableView to reload:

	override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
		super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
		self.size = size
		NSLog("viewWillTransitionToSize self.size = \(self.size)")

And when dequeueing new cells, we set the constraint its constant:

	override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
		let cell = tableView.dequeueReusableCellWithIdentifier("TestCell") as CustomTableCell!
		cell.nameLabel.text = self.items[indexPath.row]
		if self.size.width > self.size.height { //Landscape
			cell.trailingConstraint.constant = 100
		} else { //Portrait
			cell.trailingConstraint.constant = 0
		return cell

Because viewWillTransitionToSize() is not called when the View Controller is run for the first time, I also added the following code to viewWillLayoutSubviews():

	override func viewWillLayoutSubviews() {
		// Only run once, upon first display
		if self.size == CGSizeZero {
			self.size = self.tableView!.frame.size
			NSLog("viewWillLayoutSubviews self.size = \(self.size)")

layout uitableviewcell depending upon device orientation.gif

Download the example project:

Note: I created the above truly breathtaking animated gif by taking a screen recording with QuickTime Player, running the iOS Simulator, then converting the resulting .mov file with the following ffmpeg command:

  ffmpeg -i -r 15 example.gif

ffpmeg was installed via Homebrew.


Weblog Archive

Weblog entries 2014

Weblog entries 2013

Weblog entries 2012

Weblog entries 2011

Weblog entries 2010

Weblog entries 2009

Weblog entries 2008

Weblog entries 2007

Weblog entries 2006

Weblog entries 2005

Weblog entries 2004

All weblog entries


Articles, chronologically (latest first). This is pretty old stuff.


Not yet finished. Maybe will never be finished. Maybe they'll get deleted. Who knows?


System administration: