mogenerator 1.28

What’s New:

  • [NEW] --v2 argument. I wanted to enable ARC by default, but decided to take it a step further (while not breaking existing scripts). The new --v2 argument is basically semantic versioning for tool arguments.

    So now instead of this:

    mogenerator --model MyDataModel.xcdatamodeld \
        --template-var arc=true \
        --template-var literals=true \
        --template-var modules=true
    

    You can write this:

    mogenerator --v2 --model MyDataModel.xcdatamodeld
    

    Internally these invocations are equivalent, but new scripts and manual invocations should use the --v2 variant.

    I recommend putting the --v2 in front of the rest of the arguments to call attention to the versioned context of the following arguments.

    This mechanism should allow mogenerator to continue to supply sensible defaults into the future as well. Perhaps --v3 will generate Swift by default. Speaking of which…

  • [NEW] Experimental Swift code generation. Unfortunately basic Core Data functionality (to-one relationships) is broken on 10.9, but we can still try writing theoretically-correct Swift code. Perhaps a future version of mogenerator will supply the needed work-around code for you. (Alexsander Akers, afrederick1, Piet Brauer, rentzsch, Chris Weber, Markus Chmelar, Brent Royal-Gordon)

  • [NEW] Ordered relationships actually work. OMG. I have them working in a new separate OS X test app, even though mogenerator’s test dir fails. I still haven’t figured out why, but I’m not holding this back. (Daniel Tull, Joshua Greene, Dave Wood, Jonathan del Strother)

  • [NEW] Custom scalar types. Specify attributeValueScalarType for the name of the property’s custom type and additionalHeaderFileName if you need to bring in an additional header file for compilation. With this, mogenerator supports C-style and JREnum-style enums. (Quentin ARNAULT)

  • [NEW] Remove unnecessary empty lines in the generated files. (Stephan Michels)

  • [NEW] Ability to forward-declare @protocols for i.e. transformable types. Specify them via a comma delimited string in the entity’s user info under the attributeTransformableProtocols key. (Renaud Tircher)

  • [NEW] Generate *UserInfo key/value pairs as const structs. (Jeremy Foo, rentzsch)

  • [NEW] --template-var literals which, when enabled, generates Obj-C literals. (Brandon Williams, Thomas van der Heijden, rentzsch)

  • [NEW] Specify --template-var modules=true option to avoid treating #import as an import of module 'CoreData' [-Wauto-import]" warning. (Daniel Tull)

  • [NEW] Unsigned integers are generated when a property’s minimum is set to 0 in the Xcode modeler. (Dan Pourhadi)

  • [NEW] Add support for setting command-line options via a JSON config file. (Simon Whitaker)

  • [NEW] Add CONTRIBUTING.md file. It’s now even easier to contribute to mogenerator :) (rentzsch)

  • [NEW] Add MIT LICENSE file to make it clear templates are under the same license. (rentzsch)

  • [CHANGE] Suppress generation of -setPrimativeType: method. issue 16. (rentzsch)

  • [CHANGE] Add a warning when skipping an attribute named ‘type’. (Simon Whitaker)

  • [CHANGE] Add explicit atomic to sooth -Weverything. (Daniel Tull)

  • [CHANGE] iOS 8 changes objectID from a getter into a property, resulting in a warning. Templates updated to match. (Ryan Johnson)

  • [FIX] Support newly-created models when --model=*.xcdatamodeld. issue 137. (Sergey)

  • [FIX] Minor warning fix, 64->32 truncation, format strings. (Sean M)

  • [FIX] Machine headers always #imports their superentity if present. (David Aspinall)

  • [FIX] Fetch requests whose predicate LHS specifies a relationship. issue 15. (rentzsch)

  • [FIX] Don’t emit empty *UserInfo structs. (Jeremy Foo 1 2)

  • [FIX] Don’t emit empty *Attributes, *Relationships, and *FetchedProperties structs. (Daniel Tull)

  • [FIX] MOIDs subclass their superentity (instead of just always inheriting from NSManagedObject). (Daniel Tull)

  • [FIX] Don’t touch aggregate include files if the content didn’t change. (Stephan Michels)

  • [FIX] Don’t attempt to #import "NSManagedObject.h" even in the face of weird (corrupted?) model files. issue 42. (rentzsch)

  • [TEST] Escape spaces in mogenerator build path. (Daniel Tull)

mogenerator Sep 10 2014

Unpopular

Social approval is like sweetness — a signal crucial for survival for the majority of humankind’s existence that in our modern era is so prevalent that it can be toxic.

Identifying sweet foodstuffs in our hunter-gatherer era indicated carbohydrate-dense foods. The school of hard evolutionary knocks hard-wired a craving for sweet foods and gives us pleasure when we ingest them. It got us through the winters.

Once beneficial, this trait is now unfortunately out of step with humankind’s newfound ability to manufacture and consume enough sweetness that it literally makes us sick.

Social approval is likewise crucial for survival. Can’t let your “approval rating” drop so low that you’ll be ousted from your tribe and left to forage alone and die childless.

So we do things that garner approval. That’s always been the case. It’s not all bad but it’s not all good.

What’s new is that Internet social networks allows us to crowdsource social approval. As with the large-scale manufacturing of sweetness, our newfound manufacturing of social approval impacts our arthritic social structures.

It’s never been easier to garner social approval from vast numbers of people. And it’s never meant less. But like chasing sweetness’s empty calories, our lizard brains keeps us on the social approval treadmill.

Like sweetness manufacturing, social approval manufacturing can also make us sick. While social approval has incredible upsides including evolutionary advantage, it also commonly leads to shallow groupthink and hindering of true progress.

Don’t misconstrue that I’m arguing that you shouldn’t care at all what others think and approve of. Tribes provide valuable insights and checks on your experiences and evaluations. But social approval is like salt — even if you ban it from your home chances are its pervasiveness in our society will be more than enough to meet your daily requirement.

Unpopular is my Chrome extension that helps dampen the social approval echo chamber. It hides indicators of social status on GitHub (followers, watchers, stars, forks) and Twitter (followers, retweets, favs).

I find Unpopular useful to focus on what I find interesting and important.

I hope you find it useful as well.

unpopular chrome crx Jun 28 2014

JRTranscriptView 1.0

JRTranscriptView is my new purpose-built text view for logging output.

It scrolls like you think it should.

Requires iOS 7+ and Xcode 5.1+.

jrtranscriptview Apr 14 2014

Apple Claims Mogenerator’s Methods

When generating class files to represent your data model’s entities, mogenerator writes a few convenience class methods for you:

+ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_;
+ (NSString*)entityName;
+ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_;

These handy class methods allow you to write something like this:

[MyEntity insertInManagedObjectContext:moc];

to create a new instance. Contrast with:

[NSEntityDescription insertNewObjectForEntityForName:@"MyEntity" inManagedObjectContext:moc];

The mogenerator way is more obvious, less code and not stringly typed.

So that’s the backgrounder.

The good news is Apple likes mogenerator so much that they used it to implement iOS’s PhotoLibraryServices.framework.

The bad news is that PhotoLibraryServices.framework is a private framework.

As a first line of defense against naughty developers submitting apps that use undocumented APIs, Apple sweeps up every selector (method name) defined in all private frameworks and puts them on a special list. The “non-public selectors” list.

Unfortunately this includes the convenience methods mentioned above.

If your App Store submission is found to be use non-public selectors Apple may do nothing, issue a warning or reject your submission altogether.

※ ※ ※

I’m not sure what to do about this.

I could not supply the convenience methods and use Core Data directly like an animal. No! I won’t go back. I can’t go back.

Prefixing the methods (perhaps with an mo_) would provide relief, but only temporarily. When Apple upgrades PhotoLibraryServices to the newer version of mogenerator the cycle would begin anew.

NS is designed for optional class namespacing, but its concepts could be applied to method names as well. Unfortunately at the method level it uglies up the code and confuses Xcode’s code navigator popup menu. Also it would probably require NS_NAMESPACE preprocessor symbol be defined at the target or project level.

Apple could explicitly whitelist mogenerator’s convenience methods but I’m not holding my breath.

The next version of mogenerator could be released under an “Anyone But Apple” license. The idea is to allow everyone but Apple to use mogenerator. I could prefix the methods and issue the mogenerator upgrade knowing Apple couldn’t upgrade and claim the new methods as their own again.

Sadly, this seems like the most promising option.

(Thanks to Tony Arnold for the wording for the title of this post.)

Update Apr 18: First off, a clarification: it appears Apple has never rejected an application using mogenerator’s methods — they’ve only issued warnings.

Now for the good news: a little birdie has told me Apple has whitelisted mogenerator’s methods.

mogenerator appstore Apr 12 2014

Apps I Love: Acorn

I’m surprised I haven’t already written about Acorn under my Apps I Love tag.

Acorn long ago freed me from having to install Photoshop on my Mac. Thank goodness.

I’m not a graphics professional. Acorn does way more than I need it to do. But those “extra” abilities never get in my way. And when I do need to do something a little beyond my common tasks, Acorn has always delivered.

That’s how Mac apps should be.

appsilove acorn Apr 7 2014

AutoLayoutShorthand 1.0

AutoLayoutShorthand is my new(-ish) library for creating and adding Cocoa Auto Layout constraints.

Even with Visual Format Language (VFL), Auto Layout is verbose.

AutoLayoutShorthand strives to highlight the intent of your constraints with a simple literal dictionary-based syntax.

AutoLayoutShorthand also eliminates the need for stringly-typed code, you’ll get compile-time errors when you forget to update a view’s variable name. Xcode features like Edit All in Scope will also work.

AutoLayoutShorthand seamlessly simultaneously supports both iOS and OS X: the same constraint code works with both UIViews and NSViews.

autolayout als autolayoutshorthand Apr 6 2014

Using ownCloud for Contacts and Calendar Syncing (instead of iCloud)

OS X 10.9 removed the ability to sync your contacts and calendars between your Mac and iOS device via direct USB connection. (Though it’s rumored to reappear.)

The removal of this feature was sadly unadvertised. I only noticed when I updated my sister’s address on my Mac and it never showed up on my iPhone. I probably would have put off upgrading to 10.9 if I had known about its removal ahead of time.

Apple’s preferred contact and calendar syncing method is now via its iCloud service.

However, I don’t want to use iCloud since Apple has a poor track record with online services (in both longevity and correctness) and I’d prefer not to upload my private information.

Fortunately both OS X and iOS also support CardDAV for contact syncing and CalDAV for calendar syncing. I decided the time had come for me to make the jump and host these services myself, for myself.

OS X Server has built-in support for workgroup contact and calendar sharing, however I’ve learned through extensive painful experience to avoid it.

Apple open-sourced their Calendar and Contacts Server, and I investigated using it as my personal server. Unfortunately the dependencies were steep (PostgreSQL and Memcached required), Linux support nonexistent and basic instructions about how things work were lacking. I have a sad sordid history of dealing with unsupported Apple software, and I decided against adding CalendarServer to the heap.

Fortunately I read about Alex Payne’s Sovereign project when he announced it and I remember it had contacts and calendar support. I looked into it a bit more, and discovered those services were provided via ownCloud.

So I spun up a new Ubuntu Server 12.04.3 LTS VM on VMWare Fusion on my Mac mini sitting at Mac Mini Vault and installed ownCloud 6:

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get dist-upgrade
$ sudo reboot
$ sudo su -
$ wget http://download.opensuse.org/repositories/isv:ownCloud:community/xUbuntu_12.04/Release.key
$ apt-key add - < Release.key
$ echo 'deb http://download.opensuse.org/repositories/isv:ownCloud:community/xUbuntu_12.04/ /' >> /etc/apt/sources.list.d/owncloud.list
$ apt-get update
$ apt-get install owncloud
$ sudo a2enmod headers
# s/AllowOverride None/AllowOverride All/:
$ sudo nano /etc/apache2/sites-available/default
$ sudo service apache2 restart

I think that’s enough to get ownCloud 6 running on Ubuntu Server using its SQLite backend. You can add MySQL to the mix if you think you need it (10+ users, speed, scale).

Then I created a self-signed SSL cert:

$ openssl genrsa -des3 -out myssl.key 1024
$ openssl req -new -key myssl.key -out myssl.csr
$ cp myssl.key myssl.key.org
$ openssl rsa -in myssl.key.org -out myssl.key
$ openssl x509 -req -days 365 -in myssl.csr -signkey myssl.key -out myssl.crt

I installed my self-signed cert on my Mac and iPhone (via Dropbox’s Public URL sharing) and rebooted.

I ended up entering the following URL into Contacts.app:

https://example.com/owncloud/remote.php/carddav/principals/wolf/

And into Calendar.app:

https://example.com/owncloud/remote.php/caldav/principals/wolf/

I was worried what would happen when added these URLs to my iPhone. Would I wind up with a mess of duplicate records? Should I first tediously delete all my existing records, one by one? Fortunately, upon addition of these new data sources, my iPhone offered to delete all existing Calendar and Contact entries. I took the leap of faith and it worked out. Phew.

A final snag is that apparently iOS CardDAV implementation apparently attempts to HTTP GET https://example.com/.well-known/carddav before allowing addition of the CardDAV source to ensure a working service, I guess. ownCloud knows nothing about this, but it’s easy to support what iOS is looking for adding a URL rewrite to your web server config. Here’s my nginx rule:

rewrite ^/.well-known/carddav /owncloud/remote.php/carddav/ redirect;

I’ve been using ownCloud for about four months now and have been happy with it. I’m happy to be able to use cloud syncing without being beholden to a questionable cloud provider.

owncloud sysadmin icloud carddav caldav Mar 28 2014

JREnum 1.1

What’s New:

  • [NEW] Add support for hex constants. (Alex Gray)
  • [NEW] Add support for very simple bit-shifting constants. (rentzsch)

Previously.

jrenum Mar 25 2014

Apple Close-Sources IOUSBFamily

Landon Fuller / @landonfuller:

My IOUSBFamily radar: “The issue is not going to be addressed … We discourage developers to do anything in kernel”: pic.twitter.com/NrifEvOKMn

If this Radar response is accurate, it appears Apple will no longer publish OS X’s IOUSBFamily source code.

apple kext Mar 24 2014

man’s Special Xcode Support

The backstory: I use ManOpen to view Unix man pages on OS X. (schwa has a modernized fork on GitHub.)

It stopped working. Perhaps with 10.9 Mavericks or 10.8 Mountain Lion. I was too busy to track it down.

Today I was trying to look up memcmp's page and it was still broken. I figured Apple just moved where man pages live and I needed to add the new search path to ManOpen's prefs.

However, I couldn’t figure out the right path. I knew man memcmp somehow worked, and I used sudo find / -name 'memcmp.3' to locate where man was finding its page:

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/share/man/man3/memcmp.3

I added that path to ManOpen and it worked, but I was troubled that 1) it seemed way too specific and 2) I didn’t know how man was finding the page in the first place.

I took a look at /etc/man.conf and /etc/manpaths and /etc/manpaths.d to no avail. They pointed me towards /usr/share/man (which is a ghost town on my system) and /usr/local/share/man (which was also incomplete (it didn’t have memcmp.3)).

So I tweeted:

rentzsch / @rentzsch:

what’s the deal with man pages on OS X 10.9? man memcmp works even though /usr/share/man is a ghost town and /u/l/s/man doesn’t have it

rentzsch / @rentzsch:

looks like it’s coming from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform /Developer/SDKs/MacOSX10.9.sdk/usr/share/man

rentzsch / @rentzsch:

but I don’t understand how

rentzsch / @rentzsch:

manpaths does list that Xcode SDK path, but I there’s no entry for it in /etc/man*

Kyle Sluder figured it out in short order:

Kyle S. / @optshiftk:

Ah, here’s the magic: opensource.apple.com/source/man/man…

That’s just the patch, man's full code is here (thanks to Tom Harrington).

So Apple’s man calls xcselect_get_manpaths() to dynamically add Xcode-specific paths to man's search paths. Sneaky.

Dave DeLong also informed me about libxcselect.dylib:

Dave DeLong / @davedelong:

my guess: /usr/lib/man links libxcselect.dylib (otool -L) and it’s using that to find your Xcode SDK to look for more man pages

(typo corrected)

libxcselect.dylib is key to Apple’s technique of providing stubs binaries at standard locations that do little else but look up the actual tool locations inside /Applications/Xcode.app and execute them.

For example, let’s look at cc. /usr/bin/cc is just a symlink to /usr/bin/clang, which makes sense in modern terms. Let’s see what it links to:

otool -L /usr/bin/cc
/usr/bin/cc:
    /usr/lib/libxcselect.dylib (compatibility version 1.0.0, current version 1.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)

Your suspicions should be raised by our friend libxcselect.dylib. Also, /usr/bin/clang's size:

$ ls -l /usr/bin/clang
-rwxr-xr-x  1 root  wheel  14224 Oct 24 08:41 /usr/bin/clang

clang is cool but I doubt Apple’s fitting an entire C/C++/Obj-C/Obj-C++ compiler into 14K. Let’s take a look at what it actually does:

$ otool -tV /usr/bin/clang
/usr/bin/clang:
(__TEXT,__text) section
_main:
0000000100000f5e    pushq   %rbp
0000000100000f5f    movq    %rsp, %rbp
0000000100000f62    movq    %rsi, %rax
0000000100000f65    leal    0xffffffffffffffff(%rdi), %esi
0000000100000f68    leaq    0x8(%rax), %rdx
0000000100000f6c    leaq    0x27(%rip), %rdi ## literal pool for: clang
0000000100000f73    xorl    %ecx, %ecx
0000000100000f75    callq   0x100000f7a ## symbol stub for: _xcselect_invoke_xcrun

It’s entire implementation is pretty much just

return xcselect_invoke_xcrun("clang");

FWIW I found the real clang binary in

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang

It’s 28MB.

Anyways, I’m sticking with just adding that Xcode SDK path to ManOpen for now, but perhaps someone will enhance ManOpen to call automatically manpath instead of having to explicitly specify such paths. ManOpen is open source (hint hint).

Update: Chris Cieslak has immediately stepped into the breach and added a quick and dirty fix to ManOpen. Thanks, Chris.

xcode man manpath Feb 4 2014