[Openmcl-devel] Linking StoreKit.framework from CCL and in-app purchases

Michael Minerva minerva at agentsheets.com
Thu Apr 11 10:28:30 PDT 2013

I agree with both of your enthusiam and think it would be wonderful to have more apps in the app store.  As far as I know there are already two CCL apps in the store but none of have been added since the era of sandboxing begun.  

> I haven't had to link a new framework yet, but as I was perusing the CCL documentation the other day looking for something else I noticed section "14.7. Loading Frameworks" which references section "13.5.2. Creating new interface directories". I'm not sure if those are sufficient, but they should provide a good start for you I think.

I was able to load the framework using a call open-shared-library:

(open-shared-library "/System/Library/Frameworks/StoreKit.framework/StoreKit")

but now I am having trouble actually referencing any of the classes from the framework.  For example, there is a class called SKPaymentQueue:


This class does inherit from NSObject but cannot be referenced in the usually CCL fashion.  Its not to surprising that I ns:SKPaymentQueue does not return a class object in the same way that ns:ns-applicaiton does but I am now curious how I would reference the class after the framework is loaded.  I imagine I could call one if its functions such as canMakePayments using a call to external-function but since this is class method I would need a reference to the SKPaymentQueue class object in order for that to work.  
> I'm on the last leg of a complete rewrite of my cocoa contrib from about 3 years ago. It had gotten badly out-of-date. I've completely eliminated the need to use nib files or InterfaceBuilder, even for fairly complex interfaces. I've added what I think is a pretty neat interface to Apple's constraint functionality, added a bunch of initialize-instance :after methods for common view classes that permit access to pretty much every #/set… method for those classes (doing automatic data conversion for you as needed). That lets you do more normal sorts of lisp initialization of views. I have LOTS of lisp/obj-c data conversion that is all consolidated into a single coerce-obj method, so it's easy to remember. And there is lots more. I've also completely rewritten my various tutorials for building lisp cocoa apps with a bunch of examples. I expect it could take several weeks yet to get it all tested and then I'll check it in.

That's great this seems like very useful work!

> I doubt that there is anyone out there who is making much use of what I did previously, but if there is and you want to keep using it going forward, you may want to grab a copy before I wipe it all out and replace it with the new stuff. All my new code will require CCL 1.9 and OSX 10.7 (Lion) or better.

I personally did not end up using this code directly but it was a very useful reference and I think bringing it into the age of Lion/Mountain Leion is a wonderful idea. 

> I'm behind you on actually getting something ready for the app store, so I'll turn your question around on you. Do you have anything written down that could help others get as far as you already are? I saw an exchange you had a while back with Matthew about codesign'ing apps and that helped me a bit. What else do you have to share? What did you need to do to sandbox your app?

While I do not have any official documentation written down I would be happy to share the experiences I have had.  Keep in mind though that I have not tried submitting this app to the app store so there are likely future hurdles to overcome.  

So far here is the process we have gone through: First, we applied for an apple developers account and using this account and Xcode we were able to create a valid certificate for you application.  Initially we did this with no immediate intention of targeting the app store but we needed to have our app code signed in order for Mountain Lion to not mark us as a threat, and prevent Mountain Lion users from opening our app without adjusting their security preferences.  You can check out the free version of  our app which should run on Mountain Lion without changing security preferences (it will still advice that it was downloaded from the internet but there is no way around that):


Next we decided that we should try and push our app into the app store so our next task was to attempt to sandbox AgentCubes.  This was somewhat daunting for us because almost of all the available documentation about sandboxing makes the assumption that you are going to be undertaking the entire endeavor through Xcode and there is very little documentation outside of this use case.  I will link some of this documentation at the end.  

In short the steps required to sandbox an app without Xcode are as follows:
• A first and optional step would be to create a valid certificate and load it into your key chain. This will be a required step before submitting any app to the app store but will not be necessary just to test sandbox your app.  
• Create an entitlements plist: an entitlements plist is basically a declaration of all of the things that your app wants to do outside of the most locked down kind of sandboxing.  Some of these entitlements include: read/write to files that are not located inside the app's container, using network resources,  access to music, downloads or Movies folders, as well as many others.  One of these entitlements is the most important for sandboxing which is com.apple.security.app-sandbox which is the entitlement that enables sandboxing
• Then all you should need to do is run the codesign command  with the correct parameters.  It should look something like this: 
	codesign -s "If you have created a certificate enter the name of the certificate loaded into the key chain here" -f --entitlements "Path/to/entitlement/AppName.entitlements" "path/to/app/AppName.app"
• Finally you will need to load up your app on Mountain Lion and watch it blow up!  Then go into the console see what kind of errors you got and then go back and fix those errors.  

So that's the short of it. Now a couple of bear traps that I fell into that others attempting that same thing will likely want to try and avoid. The entitlements plist needs to be a binary.  The only way I could find to create this plist was to go into Xcode create a dummy project, enable sandboxing, add all of the keys that you need, then save everything and copy the AppName.entitlements that was created.  This is a bit tedious but is the only was I could find to create the binary entitlements plist, if anyone knows a better way to do this I would be happy to hear it.  

Also, enabling sandboxing changes the inheritance structure of some Cocoa classes.  I ran into this with our file dialogs which were using calls to orderFront: and setFrameOrigin: which are declared in NSWindow. After sandboxing, we started getting errors that the function was not recognized, this was happening because when sandboxing, the NSSavePanel and NSOpenPanel no longer inherit these methods form NSWindow.  Here is stackoverflow post that I got a decent response from:


Finally, there is NO WAY to write to files in a non user specific location without using a file dialog and the powerboxing entitlement.  This makes things like storing system wide registration information impossible (the appStore would likely reject you for trying to have a registration keys anyway, because they would want you to handle this through the app store).  

That's about all I can think of right now, it has been about a month since I did any sandboxing and I am just now getting back around to trying to push it a little further so some of this information may be a little stale but I would be happy to answer and questions or make any clarifications people may have.  I hope someone finds this information a bit useful because I have been an information leech on this  community in the past and I am happy to be able to provide just a little something back. Here is a list of apple documentation that I find minimally useful:

• Sandoxing documentaiton: http://developer.apple.com/library/mac/#documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html
• List of entitlements: http://developer.apple.com/library/mac/#documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html
• Stackoverflow post about code signing without Xcode: http://stackoverflow.com/questions/8385252/how-to-build-sandboxed-app-without-xcode
• Stackoverflow post about file dialogs and sandboxing: http://stackoverflow.com/questions/15347000/trouble-understanding-differences-in-the-nsremoteopenpanel-with-sandboxed-app  

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.clozure.com/pipermail/openmcl-devel/attachments/20130411/f305a521/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 2559 bytes
Desc: not available
URL: <https://lists.clozure.com/pipermail/openmcl-devel/attachments/20130411/f305a521/attachment.bin>

More information about the Openmcl-devel mailing list