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.)
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.
ARC has a trick that keeps returned objects out of autorelease pools if both the caller and callee are ARC.
But how does that work? One of the features of ARC is that old compiled-before-ARC code (MRC code) can call ARC code and vice-versa. But if ARC code doesn’t put a returned object in an autorelease pool that MRC code is expecting, then the object would just leak.
So ARC-ified clang code emits this function call when returning an object:
If you look at
objc_autoreleaseReturnValue's implementation, it calls
callerAcceptsFastAutorelease(). Even if you don’t read x86_64 or ARM assembly, the code’s comment is straight-forward:
/* Fast handling of returned autoreleased values. The caller and callee cooperate to keep the returned object out of the autorelease pool. Caller: ret = callee(); objc_retainAutoreleasedReturnValue(ret); // use ret here Callee: // compute ret [ret retain]; return objc_autoreleaseReturnValue(ret); objc_autoreleaseReturnValue() examines the caller's instructions following the return. If the caller's instructions immediately call objc_autoreleaseReturnValue, then the callee omits the -autorelease and saves the result in thread-local storage. If the caller does not look like it cooperates, then the callee calls -autorelease as usual. objc_autoreleaseReturnValue checks if the returned value is the same as the one in thread-local storage. If it is, the value is used directly. If not, the value is assumed to be truly autoreleased and is retained again. In either case, the caller now has a retained reference to the value. Tagged pointer objects do participate in the fast autorelease scheme, because it saves message sends. They are not entered in the autorelease pool in the slow case. */
callerAcceptsFastAutorelease() inspects the caller’s instructions and uses it to determine at runtime whether it needs to actually put the returned object in the autorelease pool or if it’s on the same ARC-team and it can be skipped (speeding things up).
※ ※ ※
Follows is the tweet-stream that led this posting, much thanks to David Smith for the education.
part of me still wants to write [NSMutableArray array] instead of [NSMutableArray new] since maayybbeee this code will be MRC one day again
@rentzsch should be just as efficient under arc, so go for it :)
@Catfish_Man I think +array still hits the autorelease pool under ARC
@rentzsch I’ll try to remember to check today and file a bug if it does
@Catfish_Man I love it but messaging sending is a serious conceptual barrier toward optimization
@rentzsch aye. I got [NSDate date] fixed to not hit the ar pool though :)
@Catfish_Man very interesting! I’m not sure how that’s possible unless you’re playing some sort of cacheing magic
@rentzsch ah didn’t realize you weren’t familiar with the general mechanism here. ARC can elide most autoreleased returns. Lemme find a link
I don’t know what’s going on, but 10.9 has freed up like eight-ten precious gigabytes on my SSD. Yay!
@rentzsch Have you checked with “df” vs. looking in Finder? I think 10.9 subtracts the space for mobile time machine from used in latter.
Sure enough Disk Utility reports 29GB free (about what I had before upgrading to 10.9) while Finder is reporting 38GB free.
Looks like Finder 10.9 now deducts the space taken up by Mobile Time Machine backups on the theory that they’re purgeable under disk-space pressure. Apple wrote a backgrounder on the topic.
I think this new feature is quite reasonable if a bit initially opaque.