Wednesday, December 23, 2015

Command line swift

It is perhaps quixotic (unrealistic or impractical), but I like doing things without Xcode sometimes. Xcode is a complicated beast. So in testing code I've been doing

swift test.swift

from the command line, updated from

xcrun swift test.swift

which I used to do.

I was excited to find that it is possible to use code in more than one Swift file, like this:

swiftc file1.swift main.swift -o prog
./prog


Credit:
http://stackoverflow.com/questions/29089861/how-to-import-modules-without-an-xcode-project-in-swift


Reading the man page for swift and swiftc I find these ideas:

swiftc -emit-library card.swift

which runs and gives libcard.dylib but I have no idea how to import it from Swift.

There is also -emit-module, which gives card.swiftdoc and card.swiftmodule but I have no idea how to use them.

Maybe I should look inside Xcode and try to figure out how it accomplishes what it does?

CommonCrypto5

I came across another introductory article about how to import CommonCrypto from Swift.

Recall what we did before following this post:

Method 1:

- obtain a bridging header by adding a dummy Objective-C file in Xcode
- in the header, do #import <CommonCrypto/CommonCrypto.h>

The library functions will be available from an Xcode Swift Cocoa app project.

Method 2:

Make CommonCrypto quack like a Framework by putting a file module.map with appropriate code, inside the directory that holds OS X SDK frameworks:


/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform\
/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks


With that single change:

- we no longer need the bridging header from an Xcode project
- we can use CommonCrypto in a framework
- we can use it in an Xcode Playground

- we can also do this:


test.swift:
import CommonCrypto
print(CC_SHA1_DIGEST_LENGTH)

> swift test.swift
20
>


The referenced article shows a different way to use CommonCrypto inside a framework (where the bridging header trick won't work).

Put the module.map

module.map:
module CommonCrypto [system] {
header "/usr/include/CommonCrypto/CommonCrypto.h"
export *
}


inside your project directory (not necessary to use Xcode). Following the instructions:

Now add the new module to Import Paths under Swift Compiler – Search Paths in your project settings. Use ${SRCROOT} in the module path (e.g. ${SRCROOT}/CommonCrypto) to insure that the project works no matter where it’s checked out.

Then you can just use import CommonCrypto.

Other notable items:

- use of NSData and NSMutableData types for the buffers
- size_t(key.length) and size_t(data.length), in calling the functions

Tuesday, December 22, 2015

Swift 2 book

I've been reworking my "book" on Swift, to update from Swift 1 to 2 and add some more examples. It is still early days, but after a week of work I am ready to put up a rough draft here.

You can read it right there on github, or you can clone the project and build the html with Sphinx if you have that. Here is a gist of a small part of it:

Wednesday, December 16, 2015

A bit more about pointers in Swift

I looked into the problems with Open SSL under Swift a bit more. To reassure myself that I can still deal with C pointers, I wrote a quick demo. Here is the gist:



We will print an array passed into the function f1, modify that array in place in f2, and change each value to a different data type and write that to a second array in f3.

f3 takes the fourth root. Because the resulting type is a floating point number (I used a double), I need a second array into which the values are written. It works as you'd expect:


> clang -Wall p1.c -o prog
> ./prog
f1
1 2 3 4 5
f2
1 4 9 16 25
f3
1.00 1.41 1.73 2.00 2.24
>


And the point is that the code to use this C "library" from Swift is trivial. To keep path issues away, I simply added this C file to a new Xcode Cocoa app project written in Swift. I get a bridging header in the usual way, and add to it a statement #import "p.h", as well as dragging the header into the project.

p.h:

void f1(int *, int);
void f2(int *, int);
void f3(int *, double *, int);


To actually use the C code, we just do this in a function called from the AppDelegate:



It prints:


Swift: a = [1, 2, 3, 4, 5]
f1
1 2 3 4 5
f2
f1
1 4 9 16 25
Swift: a = [1, 4, 9, 16, 25]
f3
Swift b: 1.000 1.414 1.732 2.000 2.236


And this code never ever crashes. Well, not that I observed, anyway. I got the idea of testing whether it would crash in 100 trials. In a shellscript:


n=1
while [ $n != 100 ]
do
    open -a "MyApp"
    sleep 1
    osascript -e 'quit app "MyApp"'
    n=$((n+1))
done


open we know, but using osascript to kill an app, that's special.

Although this runs, I got to thinking it probably won't report a crash. I should try Python.



It's actually fairly annoying, because each time the app launches, it grabs the focus!


97
98
99
100
>


That's a relief.

Anyway, it's not hard to puzzle out where we need UnsafeMutablePointer<Int32> and where we need UnsafeMutablePointer<Double>.

Of course, we knew this was robust, because CommonCrypto worked so well.

The problem seems to be in Open SSL. I just started learning to use the debugger lldb. But it is clear that the crash that occurs when we have called AES_set_encrypt_key often occurs sometime later, after the enclosing function test returns, or even back in the AppDelegate. We are not messing up the call.

I don't know how to fix that.

Monday, December 14, 2015

Carthage

This morning I was ready to move on to openssl and try to use that in a Swift Cocoa app. I came across this, which talks about Cocoapods.

So what is that? It is a dependency manager for iOS and macosx. If you want to add various libraries to your app, this will help keep the versions straight. Then I became aware that there is another such beast called Carthage. And I immediately liked their philosophy: "ruthlessly simple."

And their background at github.

So I worked through this tutorial, which didn't work in part, but that may be because it's about iOS, and I don't know much about iOS.

Here is the bottom line: we can get Carthage with Homebrew:

brew install carthage

Take a look:

> brew info carthage
carthage: stable 0.11 (bottled), HEAD
Decentralized dependency manager for Cocoa
https://github.com/Carthage/Carthage
/usr/local/Cellar/carthage/0.11 (29 files, 11M) *
Poured from bottle
From: https://github.com/Homebrew/homebrew/blob/master/Library/Formula/carthage.rb
>

Using it is really simple. We make a new Xcode project (UseEncryptor) that will use the Encryptor framework (which is on github here).

(It will also work with SSH).

In the root directory of UseEncryptor

> touch Cartfile
> open -a Xcode Cartfile

Put this text:

github "https://github.com/telliott99/Encryptor" "master"

The "master" part is important. A fundamental use of Carthage is to get compatible versions of all the frameworks/libraries you need. Since I don't have versions, I need something there. It could be a specific commit, like "bf155b9".

> carthage update
*** Fetching Encryptor
*** Checking out Encryptor at "6d1f5025d33657220a77850253f83aacc41e439c"
*** xcodebuild output can be found in /var/folders/1l/d7lmw_ln5hb933r7jbkt6mq00000gn/T/carthage-xcodebuild.Lbpiz6.log
*** Skipped building Encryptor due to the error:
Dependency "Encryptor" has no shared framework schemes

If you believe this to be an error, please file an issue with the maintainers at https://github.com/telliott99/Encryptor/issues/new
>

So at first I had an error because I didn't have "master" but there was a second one, it is important to check the box "shared" under Build schemes

:

Now:

> carthage update
*** Fetching Encryptor
*** Checking out Encryptor at "bf155b9f4334ecc1f78ebcd357762eda8ebdbff6"
*** xcodebuild output can be found in /var/folders/1l/d7lmw_ln5hb933r7jbkt6mq00000gn/T/carthage-xcodebuild.t4Q2Vh.log
*** Building scheme "Encryptor" in Encryptor.xcodeproj
>


The compiled libraries are placed in folders under UseEncryptor/Carthage/, but we need to add them to the project.

For example, by dragging from the Finder window (in /Build) into the shared libraries thingie in Xcode.

Now just add this to the AppDelegate:



Debug window:

key:
pw: mypassphrase
data: b7c673d78aa3363fd1b1be53672be05f6462991e
salt: 698e91585662
iv:
3356a1155a40b509788bad7897e6434f


It works! It will also work for local files, as long as they are git repositories; e.g. the Cartfile could say:

git "file:///Users/telliott_admin/Swift-Frameworks/Encryptor" "master"

CommonCrypto4

This is the last post about CommonCrypto. I just wanted to mention that I converted Encryptor into a framework. It is still on github.

I also wrotesome command line utilities in Swift that use it. That project is here.

You can checkout the README which explains usage.

Sunday, December 13, 2015

CommonCrypto3

This is a brief note about a big project (at least for a one-day thing). I finished a Cocoa app that implements basic AES-mode encryption and decryption from the CommonCrypto library. It does not do any I/O.

For now, you can just watch it run in the debugger, using pre-formed messages. But it can handle messages that are larger than a single block by breaking the data into blocks and encrypting/decrypting each one.

One nice thing is the BinaryData class, which implements some functionality around a [UInt8] including the Indexable and CustomStringConvertible protocols, and a convenience initializer that takes a String representing binary data.



BinaryData is a class because it has a derived class Key, which implements key "stretching" from CommonCrypto.

At the very end, I ran into trouble because I did not really understand the CBC protocol.

When encrypting, the output ciphertext becomes the initialization vector for the next round. But when decrypting, the input (which is also the ciphertext) becomes the initialization vector for the next round.

Here is the output for a test:


pw: my secret
salt: 3356ec169bb6
msgText: a much longer and still really big secret
61206d756368206c6f6e67657220616e64207374696c6c207265616c6c792062696720736563726574
encryptMany
encrypt round: 1
encryptOneChunk
msgLen: 16
msg:
61206d756368206c6f6e67657220616e
keyLen: 16
iv:
39131435ae3d5bbf2e300ab5edddc8c9
status: 0
result:
55bd582296f708842e5d0833e3673a99

encrypt round: 2
encryptOneChunk
msgLen: 16
msg:
64207374696c6c207265616c6c792062
keyLen: 16
iv:
55bd582296f708842e5d0833e3673a99
status: 0
result:
ded208434eb0a4e753e6cdf1c41da54c

encrypt round: 3
encryptOneChunk
msgLen: 16
msg:
69672073656372657400000000000000
keyLen: 16
iv:
ded208434eb0a4e753e6cdf1c41da54c
status: 0
result:
66e7cb3ba1b51a0d657edad13de97b37

cipherData: 55bd582296f708842e5d0833e3673a99ded208434eb0a4e753e6cdf1c41da54c66e7cb3ba1b51a0d657edad13de97b37

decryptMany
decryptOneChunk
data:
55bd582296f708842e5d0833e3673a99
keyLen: 16
iv:
39131435ae3d5bbf2e300ab5edddc8c9
status: 0
result:
61206d756368206c6f6e67657220616e

decryptOneChunk
data:
ded208434eb0a4e753e6cdf1c41da54c
keyLen: 16
iv:
55bd582296f708842e5d0833e3673a99
status: 0
result:
64207374696c6c207265616c6c792062

decryptOneChunk
data:
66e7cb3ba1b51a0d657edad13de97b37
keyLen: 16
iv:
ded208434eb0a4e753e6cdf1c41da54c
status: 0
result:
69672073656372657400000000000000

decryptedData: 61206d756368206c6f6e67657220616e64207374696c6c207265616c6c79206269672073656372657400000000000000
a much longer and still really big secret


Whoa... there were some bytes in the cut and pasted text that did not appear in the debug console nor in the editor here on blogger,, but did appear in the Preview. They are the null bytes used to pad the plaintext. They do not appear in the final product. Curious...

The Xcode project is on github here.

It was a world of fun, but I think I am done with CommonCrypto for now.

Saturday, December 12, 2015

CommonCrypto2

I've been exploring how to use CommonCrypto on OS X (docs). As described in a previous post, I found an article on the web which describes how to make the CommonCrypto library available to Swift playgrounds as well as Swift Cocoa applications.

I decided to look into it a bit more. I had help from Mike Ash, as well as another knowledgable guy. Looking at the header helped a lot as well. It is extremely detailed. Since the project was somewhat challenging, I thought I would sketch out what I learned and post the code.

CommonCrypto is a C library. So, for example, the function that does one-step encryption or decryption, CCCrypt, is declared like this in CommonCrypto.h



The first two arguments can be defined in Swift like this:

let operation = CCOperation(kCCEncrypt)
let algorithm = CCAlgorithm(kCCAlgorithmAES)

We're first going to encrypt, and the encryption scheme will be AES.

If we look in the header, it tells us that the block size for AES is 16 bytes or 128 bits.

kCCAlgorithmAES128 Advanced Encryption Standard, 128-bit block

Reading further
One option for block ciphers is padding, as defined in PKCS7; when padding is enabled, the total amount of data encrypted does not have to be an even multiple of the block size, and the actual length of plaintext is calculated during decryption.

Another option for block ciphers is Cipher Block Chaining, known as CBC mode. When using CBC mode, an Initialization Vector (IV) is provided along with the key when starting an encrypt or decrypt operation. If CBC mode is selected and no IV is provided, an IV of all zeroes will be used.

To begin with we'll use ECB with PKCS7 padding because it seems simpler.


let options = CCOptions(kCCOptionPKCS7Padding | kCCOptionECBMode)


CCCrypt takes three arguments of type const void * and one of type void *. The three const arguments are the key, the initialization vector iv, and the plaintext or data (dataIn). These can be provided as Swift arrays: [UInt8], or even (for the key and plaintext) as Swift Strings. No need for NSData or UnsafePointer or whatever.

The return type for this function is CCCryptorStatus, which is 0 for success, and something else for an error. The codes are also shown in the header:



So, when I received -4301 as the result, which at first I thought was garbage, CCCrypt was actually telling me "insufficient buffer provided for the specified operation."

Of special note: I found that although the message does not have to be 128 bits or a multiple, the key does. If it is not, the encrypt operation returns 0 for success and some encrypted data, but when decrypted we don't get our plaintext back!

A buffer is needed, into which the encrypted data will be written.

let bufferSize = 128
var cipherData = [UInt8](count: bufferSize, repeatedValue: 0)
var resultLen = 0
var status: Int32 = 0

Another thing that confused me was that these sizes (except for resultLen and status) are in bits, not bytes.

When the buffer is passed into CCCrypt we need a cast:

UnsafeMutablePointer<Void>(cipherData)

We provide the address of the Int variable &resultLen, and after the function returns, that value tells how much data was written.

Finally, the other argument is the initialization vector iv.



In our first pass at this, we specify ECB mode and PKCS7Padding, so no IV is needed, and we just pass nil for this argument.

It works. The first 9 bytes of the output at the end are the same as what we put in. I put the playground on github here.

The only thing I haven't figured out with this one is how to know the size of the message when decrypting.

The second approach uses CBC. It's the same as the first, except we change the options to the default

let options = CCOptions()

define an initialization vector, and then fill it with random bytes.

var iv = [UInt8](count: blockSize, repeatedValue: 0)
SecRandomCopyBytes(kSecRandomDefault, blockSize, &iv)


Other than that, the only thing is to be sure and pad the message to 16 bytes. It works. The playground is here.

UPDATE: I implemented the other code sketched out in Mike's article: encrypting in steps for a longer message (playground), and key stretching (playground).

Thursday, December 10, 2015

CommonCrypto

So Apple has a cryptography library called CommonCrypto (docs). Importantly, it is not a framework.

Here is a quote from the older documentation (last year):

Common Crypto
In OS X v10.5 and later and iOS 5.0 and later, Common Crypto provides low-level C support for encryption and decryption. Common Crypto is not as straightforward as Security Transforms, but provides a wider range of features, including additional hashing schemes, cipher modes, and so on.

Normally, I would have passed on this in favor of, say, trying to build openssl and then access that. (I recall seeing something from tptacek about it along the lines of use something more standard, don't trust that Apple will implement the basics correctly). Judging by history, that would be pretty sage advice.

But ... I came across a wonderful blog post here, which describes not only how to use CommonCrypto from Swift, and not only shows an in-progress library wrapping CommonCrypto, but also describes a hack that allows Swift playgrounds to have access to CommonCrypto. Too cool for words!

The basics: open a new Xcode project in Swift and call it MyApp. We need a "bridging header", we get this by adding a new Objective C class, then Xcode will ask if we want this header, and we say yes. Ungratefully, we promptly delete the dummy Objective C class. In the header, add:

#import <CommonCrypto/CommonCrypto.h>


That's it. For example, I put this code into crypto.swift



and call it from the AppDelegate in applicationDidFinishLaunching. The debugger prints:

e4d909c290d0fb1ca068ffaddf22cbd0

If I put the same text in a file and do

> md5 msg.txt
MD5 (msg.txt) = e4d909c290d0fb1ca068ffaddf22cbd0
>


Of course, what we've done here is the usual C hack of allocating a buffer and passing a pointer to the buffer into the program that will write into it. Except that in Swift these are not your father's pointers. You can't do arithmetic. And they have that label "Unsafe". Reminds me of Maverick.

Now for the cool part. Deep within Xcode there are one (or more for some people) SDKs. Software Development Kits.

> xcrun --show-sdk-path --sdk macosx
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform\
/Developer/SDKs/MacOSX10.11.sdk

and deep within that is:

> ls /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform\
/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks
AGL.framework
AVFoundation.framework
AVKit.framework
Accelerate.framework
...

As I said, CommonCrypto is not a framework. But we can fake things like it is one. We make a directory in that place, call it CommonCrypto.framework and inside that put module.map with some paths:

module CommonCrypto [system] {
header "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform\
/Developer/SDKs/MacOSX10.11.sdk/usr/include/CommonCrypto/CommonCrypto.h"
header "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform\
/Developer/SDKs/MacOSX10.11.sdk/usr/include/CommonCrypto/CommonRandom.h"
export *
}

(Those line breaks should work, but I don't have them in my original).

I did this:

cd /Applications/Xcode.app/Contents/Developer\
/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk\
/System/Library/Frameworks
> sudo mkdir CommonCrypto.framework
Password:
> sudo cp ~/Desktop/module.map CommonCrypto.framework
>
> cat CommonCrypto.framework/module.map
module CommonCrypto [system] {
...
>


Having "corrupted" the SDK in this way, we can now do things like this: paste that same code into an Xcode playground. I had to change the last line, not sure why just at the moment..



And with this setup, we no longer need the bridging header. I tried just deleting it but Xcode knows. So delete the whole project and make a new one with the same name. Add the code in crypto.swift and put import CommonCrypto in that same file. Then from the AppDelegate, call doIt.

It works!



It's worth pointing out that simply substituting SHA256 for MD5 in the code above works. To check the digest on the command line do:

> openssl dgst -sha256 -hex msg.txt
SHA256(msg.txt)= ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c

Swift using a C framework

Recently I explored how to write a framework in Swift and then import and use it in my Swift app. The key elements are to find a good place to stash the framework (I used ~/Library/Frameworks), and to properly let Xcode know that it should link that framework into the app.

The objective for this post is to learn how to import and use a framework not written in Swift. Before I use a real one (like this) for today I am going to use a very simple example written in C, following this post from a few years ago.

Here is the code, which provides amazing functionality:

There is a slight wrinkle. In the original version, we didn't use a header file but instead declared the functions as extern like this:

extern int f1(int x);

within the file that uses them.

As an aside, note that I should probably have used #import rather than #include. See for example, here. However, I had already gone through twice re-testing the steps for today's post, and I didn't want to do it all again.

Now we do:

> clang -g -Wall -c add*.c
>

which generates add1.o and add2.o. Then

> clang -g -Wall useadd.c add1.o add2.o -o useadd
>


> ./useadd
f1: 1; main 2
f2: 10; main 12
>

Although we didn't explicitly tell clang about add.h (i.e. in the command line invocation), it is needed for this to work. I suppose clang finds the header file in the build directory.

Now, let's make an old-fashioned library. Delete useadd. Do:

> libtool -static add*.o -o libadd.a
>

We have libadd.a. Let's use it:

> clang -g -Wall -o useadd useadd.c -L. -ladd
>

And it works:

> ./useadd
f1: 1; main 2
f2: 10; main 12
>

Here we have explicitly directed clang with -L. to the build directory, where we want it to look for -ladd (short for libadd).

Now the goal is to make a Cocoa app that uses f1 and f2... whether written in Objective C or in Swift. I thought at first we would need a framework, but we don't. Just copy libadd.a into ~/Library/Frameworks. Make a new Xcode project Myapp, a Cocoa app in Objective C. Add the library to the project as described (by clicking + on Linked Frameworks and Libraries, etc.)

We still have the header issue. For this version using libadd.a I just dragged the header into the project, with copy files, and then did the import in either AppDelegate.h or AppDelegate.m.

Now, for a framework. Make a new Xcode framework in Objective C, called Adder. Drag in add1.c and add2.c and do copy files. Put the declarations from add.h into Adder.h which Xcode provided for us.

Build it. Use the Show in Finder trick to find and then drag the framework to the Desktop and then to ~/Library/Frameworks.

Try to use the framework from the command line.

I specified the path to find the header folder which is in the framework.

And it works:


> clang -g -o useadd -F ~/Library/Frameworks/ -framework Adder useadd.c\
-I~/Library/Frameworks/Adder.framework/Headers

> ./useadd
f1: 1; main 2
f2: 10; main 12
>

We move away from the command line. Make a new Xcode Project for a Cocoa app in Objective C. Call it MyApp.

In the AppDelegate do #import <Adder/Adder.h>. Fix the error that this introduces by adding the linked binary, as usual. In applicationDidFinishLaunching: do:

int n = f1(10);
NSLog(@"%d", n);

Build and run. It works. The debugger prints:

f1: 10;2015-12-10 08:33:28.318 MyApp[6168:235988] 11

Now for the last step. Make a new Xcode Project for a Cocoa app in Swift. Call it MySwiftApp. In the AppDelegate do import Adder. Fix the error by adding the framework. In applicationDidFinishLaunching add:

let result = f1(10)
Swift.print("\nresult: \(result)")

And it works! The debugger prints:

f1: 10;
result: 11

The print from C didn't include a newline. Oops.

It works without a "bridging header". If you do have to generate one of those, just add a dummy Objective C module to your project. Xcode will generate the bridging header for you.

At this point, I have the confidence to move ahead with a real project.

[UPDATE: Repeating it all again for the third or fourth time, I am unable to get the last two steps to work smoothly. The Objective C one builds with a warning "implicit declaration of function 'f1' is invalid in C99", but it runs and prints what we expect. The Swift example allows me to "import Adder" but doesn't recognize the symbol "f1".

Since it really did work before (I didn't just imagine it), there is something that I "got for free" before that I am missing now. More exploration is needed.]

[UPDATE 2: I went through every step again from scratch. It works now. I wrote it up for the book. I guess I just have to wait and see if it fails again. ]

Wednesday, December 9, 2015

Swift framework from the command line



Following up on the previous post, I want to import my new Swift framework when building, or running Swift code from the command line.

The example above shows building. It works!

I struggled with this.. and now that I know, it just seems so silly. When providing the path to the framework, don't provide the full path, just give the path to the folder that contains it ... of course. We also need the path to the SDK, which Xcode will prompt you about, should you leave that part out.

For the other method (xcrun swift file.swift) this doesn't work. That's probably not too surprising, but maybe there will be a way.

Tuesday, December 8, 2015

Building and using a framework in Swift

In the past, I've looked into the theory and some of the complications of building libraries and frameworks on OS X, much of it written up on this blog. I got interested today yesterday in the problem of building and using a pure Swift framework. I tried some of what the top hits on Google said to do, but it wasn't very helpful (because it's all iOS, and because it didn't seem to work), however, eventually I noodled out something that I think does work. I have yet to do more than skim the official Apple documentation.

According to this

Most public frameworks should be installed at the local level in /Library/Frameworks

That's our goal here. Any app that launches and then needs to find a framework should find it by searching "the usual suspects". According to the docs, the best place is /Library/Frameworks, but here I will use ~/Library/Frameworks.

Such a framework would be a dynamic framework, not static, or baked into the app. If you were to write an installer for such an app, you should take care to install its frameworks in the right place. R is a great example of how to do it right.



So in Xcode:

OS X > New Project > Framework & Library > Cocoa Framework > Swift




I named it SpeakerFramework.framework. Add to the framework a new Swift file

speaker.swift:



Having the init and speak functions both public (as well as the class itself) is required for external visibility (ref).

Build the framework.

Under Products, find SpeakerFramework.framework.



Control-click and show in Finder



then drag it to the Desktop.

For what we will do in a minute, we need the Finder to show ~/Library in an Open File dialog. With your home folder selected in Finder, do CMD-J (or View > Show View Options) and select Show Library Folder. (If you are just on the Desktop, then Show View Options shows something different).



Now for the app. In Xcode:

New Project > OS X > Application > Cocoa App > Swift




I named it MyApp.

In AppDelegate.swift add

import SpeakerFramework


This import statement gives an error and the project will not build (No such module 'SpeakerFramework').



To fix this, open ~/Library/Frameworks and drag the framework we just copied to the Desktop into that folder.



Alternatively, just do this in Terminal:

cp -r SpeakerFramework.framework ~/Library/Frameworks


Now, back in Xcode, select the project in the Project Navigator. In the tab view, select General and scroll to the bottom where it says Linked Frameworks and Libraries.



Click the + symbol below that line (not shown in the screenshot, because I only took it after I added the framework to this project).



Click Add Other... Then navigate to the framework in ~/Library/Frameworks and select it.

The MyApp project shows the framework in the General tab



Go back to the AppDelegate. The warning should be gone.



MyApp will build now. So let's use it. Edit the AppDelegate to call the speak method:



In the Debug window, we can see the expected output.



It would be nice to make a bigger statement.

I'll just outline the steps briefly. Delete the default window in MainMenu.xib. Add a new Cocoa class, subclassing NSWindowController. Have Xcode make the xib file too. Drag a label onto that window. Make it really, really big.



Hook it up to the new class (MainWindowController) as an IBOutlet, with this code for the AppDelegate:



and for MainWindowController:



Pretty impressive:



If we select Products > MyApp.app, then show in the Finder, and drag it to the Desktop, and delete everything else, except the framework in ~/Library/Frameworks, it still works. If we then do

> mv ~/Library/Frameworks/SpeakerFramework.framework/ old
> ls ~/Library/Frameworks
>




So it looks like everything is working as expected.

I thought I would snoop on the Loader as I did long ago:

> export DYLD_PRINT_LIBRARIES=1
> open -a MyApp.app

But it gives nothing. I am not sure why, yet.

Monday, December 7, 2015

Encoder

I'm fooling around with a new Swift Cocoa project. The Encoder app does encryption and decryption. I use the phrase "fooling around" deliberately because an important rule of cryptography is to use standard libraries. If you don't really know what you're doing, you certainly shouldn't "roll your own."

Here is a screenshot of the current version of the app.

At the heart of it, we are doing something trivial:

return Zip2Sequence(a1,a2).map { $0^$1 }

where a1 and a2 are binary data, i.e. arrays of integers with values between 0 and 255 (UInt8). The xor operator ^ is just what we want for both encoding and decoding.

The trick, of course, is to generate a keystream of pseudo-random numbers given a key, which is a String.

Foundation provides standard functions for obtaining random numbers:
rand, random, arc4random, arc4random_uniform.

arc4random and arc4random_uniform are preferred for really random PRNG, but lack the ability to be seeded (by the caller). Seeding is needed so that the same pseudo-random keystream sequence can be regenerated, given a relatively short key.

The rand function returns an Int32 (try rand() is Int32 in a Swift playground. So in theory it might return both positive and negative values. However, it only seems to return positive numbers, which is good, because, say -3 % 256 is equal to -3, which would cause trouble when trying to convert to UInt8. According to this (very old) file, the OS X rand uses unsigned values.

The maximum value returned is RAND_MAX, which is equal to 2147483647 = 2^31 - 1, which is also equal to Int32.max. What we want are integers in the interval [0,255], so I just do:

Int(rand()) % 256


I'm not an expert, of course, but I looked at the distribution of output of rand and it seemed sufficiently random for my purposes.

The next question is that of seeding the PRNG. You might do:

srand(UInt32(time(nil)))

The seed function srand takes a UInt32. The question is, how do we turn our key into a UInt32? What I've done so far is to use the String property hashValue / This gives an Int, which is 64 bits, and of course, may also be negative.

Here is my approach:

Having initialized everything, we just call

func next() -> UInt8 {
  return UInt8( Int(rand()) % 256 )
}

One issue I'm still working on is that of loading binary data. I know how to turn an [UInt8] into data:

let a: [UInt8] = Array(0..<4)


let data = NSData(bytes: a, length: 4)

and load data from a file with NSData(contentsOfFile:fn), but I haven't been able to figure out how to turn that back into an array of UInt8 in Swift.

I puzzled out a way around the problem, however. String will take NSData in an initializer:


Given that, I get the individual bytes from the string and use a Dictionary



As usual these days, the project is on github here. Thanks to samol for explaining how to do the gist thing.

UPDATE:

I found a way to do the data conversion mentioned above. It looks like it is probably the natural way to do this in Swift.



We use NSInputStream initialized with the NSData object. We allocate the necessary space:

var buffer = Array(count: n, repeatedValue: 0)

and then read the data into the buffer using a reference.

stream.read(&buffer, maxLength: n)

The last call returns a result, which is the number of bytes read. Alternatively, one could read byte by byte until stream.hasBytesAvailable returns false. The only thing that confused me for a while was that I had Array(0..<n) which gave Int values of 64 bits each. Without the map on line 4 the data looks like:

[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2,

which I interpret as 00000000, 10000000, 20000000 and so on. These are the decimal values for each byte, where the ordering is little-endian, with the low value byte having the first memory address.

Intel x86 processors store a two-byte integer with the least significant byte first, followed by the most significant byte. This is called little-endian byte ordering.

Apple docs. If I write the 64-bit data to a file and examine it with hexdump:

> hexdump x.bin
0000000 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00

Sunday, December 6, 2015

Images and Icons

As I mentioned previously, I've been programming again for OS X and trying to learn Swift. Although I really like Xcode, I also seek the simplicity of running Swift programs from the command line. For reasons I will explain in a minute, I was thinking about images and drawing. I remembered an example with something similar (here, with references in the link), where we had an NSView that could be drawn without any window on screen---it was not an app with a GUI. NSView's dataWithPDFInsideRect can construct a PDF and then save it to a file. The first step was to repeat this approach in Swift (although I didn't get around to repeating the actual drawing that we had before).

Here is a screenshot from the playground:

The playground itself is on github here.

This actually works! One indicator which can be seen in the screenshot is the result returned by the last call: true, shown in the results panel on the right. The file we just wrote cannot itself be found in the playground (Show Project Navigator will not help). However, Spotlight does find it, and we can then paste the path to Terminal and view it in Preview:

> open -a Preview /Users/telliott/Library/Containers/com.apple.dt.playground.stub.OSX.pdfs-D6033292-DB23-46A3-AA4D-7C17D756519F/

This behavior is likely due to sandboxing of Playgrounds. To get around it, paste the same code into a file, my example is pdf.test.swift, and then do

> cd Desktop
> xcrun swift pdf.test.swift
>

The pdf then appears on the Desktop (or whatever the current directory is).

One reason for thinking about images was that I would like an icon for my SudokuBlocks app. According to the docs, Apple requires that the developer provide a bunch of icons (10) in different sizes.

It seemed a bit much for hobbyist programming. So what I might have done at this point was to use Preview's Tool -> Adjust Size ..

Instead, I wondered if I could write a Swift command line program (again not using Xcode) that would read an image file, resize it, and write the result to disk.

Reading the file is easy. In a playground, all you need to do is to show Project Navigator, and drag the file to the Resources folder. Then call NSImage(named:"x.png"). (This Playground and all the code and other resources for this post are on github here). The result is an optional.

At this point, I got help (once again) from Mike Ash here.

As he describes, although NSImage is a container that may have one or more representations of a particular image, including an NSBitmapImageRep, he recommends that the correct way to get at the data reliably is to first draw the image into a new NSBitmapImageRep and then look at that.

The initializer is crazy, with 10 different arguments (ref).

The result is again an optional.

The next step is to go through a vaguely recalled dance with NSGraphicsContext, saving the current context, setting up a new one using the NSBitmapImageRep.

Now, any drawing that takes place is done in the image rep. And that is where we do some resizing, calling:

img.drawInRect(dst, fromRect: src, operation: op, fraction: f)

The source src is a CGRect of the size of the image we just loaded (unless you want to clip or something), The destination dst is a rect of the size of image we want to produce. By changing dst we change the reduction or magnification of the image produced. The other two values are:

let op = NSCompositingOperation.CompositeCopy
let f = CGFloat(1.0)

There are a lot of choices for operation, e.g., see here

After that we just grab the data:

let data = imgRep.representationUsingType(.NSPNGFileType, properties: [:])

(notice the empty Dictionary [:]) and write it to disk:

data!.writeToFile("out.png", atomically: true)

The code is in images.swift in the github rep. It's a bit rough. I trimmed it down and added some command line parsing, and used it to resize square png images. That code is in resizer.swift

Usage:

xcrun swift resizer.swift filename sz
xcrun swift resizer.swift x.png 256

The last thing here is about the icon for SudokuBlocks. The official docs say that you should provide 10 different images. But it turns out that it is possible to copy a single image into the project and be done with it. Click on Assets.xcassets and then double click on Appicon and there will be a place to add the files. As a test I made a new project and dragged in a 256 x 256 image. When I build and run it the image will appear in the dock. Then I went to Products and found the app, did control click and view in Finder, and dragged it to the Desktop. It looks like this:
.

And here is a screenshot with the latest version of SudokuBlocks (you can even see it in the Dock):

Sunday, November 15, 2015

SudokuBlocks



Recently I've come back to application programming for OS X after a long time away.  I reviewed my notes on Swift from last year (on github here, not updated for Swift 2 yet).  (I was a little dismayed at how little I remembered, but it mostly came back after 8 or 10 hours).

I bought a copy of Hillegass et al. new edition of their great book to write Cocoa applications, which now uses Swift.  I haven't actually done that much with the book yet, though it was a good reference on setting up an Xcode project and hooking up a custom NSView.

For my first project I re-wrote my Color Sudoku program (post about the old one here).  At the top is a screenshot from the new one.  I notice there are similar things out there on the web now, I don't know if they were invented independently or what, but I built my first one in 2006.  In any event, it isn't suitable for mobile because of the tiny squares, so it could probably never be a commercial success.

I've been consistently amazed at how easy programming in Swift has been.  When there was a programming error it was easy to diagnose and fix.  I particularly love the ability to break out function definitions to a new file on a whim (no header files really helps here).  The fact that function names are visible in all the files of a project is a little scary, but it makes this kind of refactoring easy.

I put the new project up on github here, and also put a copy on Dropbox here.  I included a built version of the app in the project folder.  You will have to temporarily "allow apps downloaded from anywhere" or alternatively, install Xcode and build it yourself from the source.

I'm sure there are bugs.  Let me know if you find one.


Friday, March 6, 2015

Stuff on GitHub

This is my first post for a while.  I just wanted to let you know that I have been learning how to use git.  My github repo is here.

I have placed a number of "books" there which I have worked on in the last year including

MyJava
MyUnix
MyCrypto (just beginning)
PyBioinformatics

Also, there is a collection of writeups on more than 60 topics in mathematics.  The tex files are on github here and the pdfs are on Dropbox here (48 MB).