Yesterday I was finally shipping an update to one of my apps, but each time I tried submitting to iTunes Connect I got back error -9000:
Invalid architecture: Apps that include an app extension and a framework must support arm64
Googling didn’t reveal too much (the project was set up fine to build for both 32-bit and 64-bit), but the following seemed to fix the issue:
Going through project.pbxproj and manually replacing IPHONEOS_DEPLOYMENT_TARGET = 7.0; with IPHONEOS_DEPLOYMENT_TARGET = 8.0; (I had set 8.0 in the UI, no idea why the file hadn’t updated)
Ensuring that the ‘Build Active Architectures Only’ was set to NO for release builds (again, I had set this in the UI, but checked it in the project.pbxproj file)
Deleting an old static library from the Frameworks group. This is the weird one, but I suspect it was what was causing the issue. The app had previously linked to a static library that had been 32-bit only, but I had long since deleted it. The app itself didn’t link against it, but there was still a link showing up for it in the Xcode project (it showed in red though, it didn’t actually exist)
The phrasing of the error isn’t great; there ought to be an ‘or’ rather than an ‘and’ in there (my app only contains a framework, not an extension).
After two years of no updates I have now updated Word Finder with new features, significant performance enhancements, and support for new iPhones. Word Finder allows you win (cheat?!) many common word games with wild card search, anagram search, Boggle search, and Letterpress search.
A brand new query execution engine that ensures all queries now execute instantly (the old version could take several seconds)
Search history
Easy entry mode for Boggle and Letterpress grids and improved entry for anagrams
Sorting options
Save your favourite words
View definitions for thousands of words via Wiktionary or the built in Apple dictionary
The Nim programming language is simple, clean language with a style that will be familiar to Python programmers, but has the performance benefit of compiling down to C. The C the compiler generates is different depending on whether you have 32-bit or 64-bit code, which makes compiling for iOS (which has to target both 32-bit and 64-bit) awkward.
In this blog post I’ll summarise how you can use Nim for components of your app. I’ve got a working version of this project available on GitHub.
Firstly, if you haven’t already, grab the compiler and compile it (don’t worry, this is easy). Then create a new Objective-C project in Xcode. I’ve called mine nim-ios-demo:
Next you’ll want to create two directories: scripts and src. Your folder structure should look like this:
The src folder is where you’ll be placing your Nim source files. In scripts you need to place my xcode_prebuild.sh script (I modified it from work by Grzegorz Hankiewicz). This script compiles the Nim source files to C and creates the merged 32-bit/64-bit files. You need to add this script as a build phase in Xcode:
There are two minor changes that you’ll need to make to the script to use it in your project:
Set the PROJECT_DIR variable
Set the PATH_TO_NIM variable
Add your Nim source files in the ‘src’ directory. In this example I’m going to use a very simple function:
# Saved as backend.nim in the src directory
proc hello*(name: cstring): cstring {.exportc.} =
result = "Hello " & $name
You can optionally add this to your Xcode project, but make sure that you don’t have Xcode set to copy or compile it! Note that we need the asterisk after the function name so that it gets exported, and {.exportc.} ensures that the name doesn’t get mangled. We also have to use cstring rather than string (Nim’s native string type) but they get bridged automatically at no cost.
Build your project. This will run the Nim compiler and generate the C files you need to include in Xcode. Go ahead and add the contents of src/build/nimcache to your project:
If you build now you’ll get a lot of warnings (50+). If you want to avoid these, add the -w flag to the files in their compile stage:
Before you can use the Nim function you’ll need to configure the Garbage Collector. Add the call to NimMain in main.m:
By using [NSString stringWithUTF8String:] we can copy the contents of the string, which ensures that when Nim cleans up the memory later (helloName) we don’t lose the string.
Finally, you can build and run the app:
Once you’re up and running it is trivial to add new Nim code to your project. So far I’ve been very impressed with the language, and I may even use it in the future in my apps.
When Apple announced Swift last summer I was excited to learn a new programming language. After having programmed almost exclusively in Objective-C (with a bit of Go, JavaScript, C#, Java, and C++ on the side) for two years I thoroughly enjoyed picking up Swift’s new concepts such as functional programming, generics, and values.
Having enjoyed my experiences with Swift, I decided to play with a new programming language each month, so since July 2014 I’ve had a Programming Language of the Month:
The amount of work I’ve done in each language has varied hugely. I only did a small amount of work in Prolog to familiarise myself with the basic concepts, but I’ve written semi-large programs in all of the others.
Learning, or at least experimenting with, a new language is a tremendous adventure for any programmer. Its been a valuable experience picking up ideas in a variety of functional, imperative and declarative programming languages. If you’ve got the time, I’d give a PLoTM a try.
Swift has encouraged many developers to consider Cocoa and Cocoa Touch development, but the vast majority of resources are still written in Objective-C. I’ve done a huge summary over on GitHub of many common patterns.
It may be tempting to rewrite existing classes in Swift, however this will generally be a waste of engineering resources. A better approach is to add functionality to existing Objective-C classes by writing categories for them in Swift. This way, if you choose, you can write all future code in Swift whilst avoiding unnecessary extra work.
Cake Day, my iOS app that reminds you once a year of your reddit cake day (birthday), has been updated with a new UI and iPad support.
Changes:
Completely removed the hamburger menu. Apple discourages these and it didn’t work brilliantly, so I decided it would be best if it went
Changed the app’s default font (now using Open Sans)
Rewrite of the app in Swift. I hadn’t originally planned to do this as part of the update, but I wanted to see whether or not Swift could improve my programmer productivity. Overall I found that the amount of code that I had to write was similar - although I now have a lot more database could for dealing with SQlite.swift than I had before when using FMDB
The app is now open source you can contribute or post issues at GitHub
You can download Cake Day for free from the App Store.
I’ve published an update to Keep Calm for iOS just in time for Christmas. This version adds PDF export for Pro users, which is great if you want to print your posters from your computer later. PDFs can be either opened in another app (Kindle, iBooks, Dropbox, etc) or shared directly (email, iMessage).
You can download Keep Calm for free from the App Store. The Pro upgrade costs $0.99.
It is a little bit of a pain to use OpenGL with Swift as GLKit is barely compatible. This is because GLKit’s math functions and types are all based off of unions, which Swift doesn’t support because they are designed to be unsafe. You are left with two choices: roll your own matrix library in Swift (which may miss out on the ARM NEON or Intel SSE performance enhancements) or hide GLKit behind some Objective-C.
I decided to go for the latter, and the product is OpenGL.swift. Instead of using unions I have used structs which contain one member:
typedefstruct { GLfloat m[16];} TDMatrix4;
I then wrapped all of GLKit’s math functions and I internally cast my matrix and vector types to the GLKit types in Objective-C code. As all of my functions and all of the GLKit functions get inlined there is no performance cost to this. My code was all generated by a Ruby script directly from the GLKit headers.
Once I had wrapped all of the GLKit math functions and types I then wrapped all of the uses of matrices and vectors in GLKit classes, so you can actually use them from Swift:
let aspect = GLfloat(CGRectGetWidth(self.view.bounds) / CGRectGetHeight(self.view.bounds))
let projectionMatrix = TDMatrix4MakePerspective(GLKMathDegreesToRadians(65.0), aspect, 0.1, 100.0)
self.effect?.transform.td_projectionMatrix = projectionMatrix
At this point I then added operator overloading using all of the standard methods, so in Swift you can concisely do matrix math:
let mvpMatrix = projectionMatrix * modelViewMatrix
As well as this I also added wrappers around the standard uniform functions so it is much simpler to submit matrix and vertex data to the GPU:
//Submitting vertex data
glBufferData(GLenum(GL_ARRAY_BUFFER), vertexData, GLenum(GL_STATIC_DRAW))
//Setting uniform data
glUniformMatrix4fx(mvpMatrixSlot, TDFalse, mvpMatrix)
You can get the source for OpenGL.swift on GitHub (there are instructions for dropping it into your project there as well).