--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
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)
--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] 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] Minor warning fix, 64->32 truncation, format strings. (Sean M)
[FIX] Machine headers always
#imports their superentity if present. (David Aspinall)
[FIX] Don’t emit empty
*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)
[TEST] Escape spaces in mogenerator build path. (Daniel Tull)
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.
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+.
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:
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.
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.
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.
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.
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:
And into Calendar.app:
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.
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:
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/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
So I tweeted:
what’s the deal with man pages on OS X 10.9?
man memcmpworks even though /usr/share/man is a ghost town and /u/l/s/man doesn’t have it
looks like it’s coming from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform /Developer/SDKs/MacOSX10.9.sdk/usr/share/man
but I don’t understand how
manpathsdoes list that Xcode SDK path, but I there’s no entry for it in /etc/man*
Kyle Sluder figured it out in short order:
xcselect_get_manpaths() to dynamically add Xcode-specific paths to
man's search paths. Sneaky.
Dave DeLong also informed me about
@rentzsch 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
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
/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
$ 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
FWIW I found the real
clang binary in
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.