Friday, 29 August 2014

Codesign on Mavericks/Yosemite: Some useful commands

Recently, Apple announced that from 10.9.5 and 10.10 onwards, the apps signed in OSX Mountain Lion and below will not be able to pass the Gatekeeper. Those signatures (v1) will be considered deprecated and you must sign your apps in 10.9 or above to have latest signature (v2).
At this point of time, it is unclear if Apple is really going to block the apps with v1 signatures. We can’t be sure until we have a GM build for OSX Yosemite. Anyway, it is better to start signing on 10.9 straightaway so that our apps are compliant to the changes done by Apple.
Following are some commands that may be useful:
Verify if any app will be accepted by Gatekeeper on 10.9.5 (OSX Mavericks) /10.10 (OSX Yosemite) or above.
vikrams-macbook-pro:~ admin$ spctl -a -t exec -vv Foo.app
Foo.app: rejected
source=obsolete resource envelope

vikrams-macbook-pro:~ admin$ spctl -a -t exec -vv Foo.app
Foo.app: accepted
source=Developer ID
origin=Developer ID Application: My Company

Sign an app:
codesign  --sign  “Developer ID Application: My Company”  Foo.app

Resign an already signed app (Use –f flag):
codesign  --force --sign  “Developer ID Application: My Company”  Foo.app 

Check the version of the signature. See the line starting with "Sealed Resources". There, version=2 indicates that this app has the new signature type as suggested by Apple:
vikrams-macbook-pro:~ admin$ codesign -dvvv Foo.app 
Executable=Foo.app/Contents/MacOS/Foo
Identifier=com.vikrams.testapp
Format=bundle with Mach-O thin (x86_64)
CodeDirectory v=20200 size=42914 flags=0x0(none) hashes=2138+3 location=embedded
Hash type=sha1 size=20
CDHash=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Signature size=7589
Authority=Developer ID Application: My Company
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Timestamp=23-Aug-2014 4:32:13 pm
Info.plist entries=17
TeamIdentifier=31ACEW5CBX
Sealed Resources version=2 rules=12 files=137
Internal requirements count=1 size=192
You can find more options for "codesign" command at its man page.

Thursday, 21 August 2014

PackageMaker and OSX Mavericks

Recently, I tried to use PackageMaker.app on OSX Mavericks and the result was a crash. The version I was using was 3.0.5. During the launch, PackageMaker crashed with following crash log.

Process:         PackageMaker [338]
Path:            /Volumes/VOLUME/Developer/AuxiliaryTools/PackageMaker.app/Contents/MacOS/PackageMaker
Identifier:      com.apple.PackageMaker
Version:         ???
Build Info:      PackageMaker-196001000000000~606
Code Type:       X86 (Native)
Parent Process:  launchd [155]
Responsible:     PackageMaker [338]
User ID:         501

Date/Time:       2014-08-21 21:59:14.963 +0530
OS Version:      Mac OS X 10.9.4 (13E28)
Report Version:  11
Anonymous UUID:  B98E910E-EB57-50EB-B983-9297F16941A0

Sleep/Wake UUID: 3DE16912-3893-4886-B367-0331B7A52488

Crashed Thread:  0

Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000002, 0x0000000000000000

Application Specific Information:
dyld: launch, loading dependent libraries

Dyld Error Message:
  Library not loaded: /System/Library/PrivateFrameworks/DSObjCWrappers.framework/Versions/A/DSObjCWrappers
  Referenced from: /Volumes/VOLUME/Developer/AuxiliaryTools/PackageMaker.app/Contents/MacOS/PackageMaker
  Reason: image not found

Binary Images:
0x8fe9e000 - 0x8fed0417  dyld (239.4) <FF5ED937-CC28-3FEF-BCAF-750B1CDBAE36> /usr/lib/dyld
0x906b1000 - 0x9085dfff  com.apple.QuartzCore (1.8 - 332.3) <DA347693-5E26-3E47-A2B3-3824C52EB08B> /System/Library/Frameworks/QuartzCore.framework/Versions/A/QuartzCore
0x9085e000 - 0x9086cff7  libz.1.dylib (53) <858B4D9F-D87E-3D81-B07A-DF9632BD185F> /usr/lib/libz.1.dylib
0x93f71000 - 0x93fb1ff7  com.apple.bom (14.0 - 193.1) <FFF1C8E5-41FF-357B-8681-69B21DCED2E4> /System/Library/PrivateFrameworks/Bom.framework/Versions/A/Bom
0x9408e000 - 0x9417aff7  libxml2.2.dylib (26) <32040145-6FD6-3AD2-B98B-39F73BF9AC47> /usr/lib/libxml2.2.dylib
0x963cd000 - 0x963cdfff  com.apple.Cocoa (6.8 - 20) <407DC9E6-BBCE-3D34-9BBB-00C90584FFDF> /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa

If you also faced a similar issue, please download the new version of PackageMaker application from Apple download center. It comes bundled inside the package named "Auxiliary Tools for Xcode". Make sure you are downloading the Auxiliary Tools dmg that came out in late July 2012. It has PackageMaker 3.0.6 which works fine on Mavericks and hopefully on Yosemite as well (though I didn't try on Yosemite).
Hope that solved your problem.

Sunday, 9 March 2014

Removing dock icon using Cocoa

Sometimes there is a need of removing a dock icon programmatically. In such cases, there are third party utilities like dockutil, available to do the task. However, there was a problem in OSX Mavericks (Mac 10.9) where dockutil failed to remove the icon from the dock. [Update: The issue in dockutil is fixed in their latest version]
If any of you faced a similar issue, you can use the Cocoa APIs to remove the dock icon right from your code. See the sample code below-




-(void) removeDockIcon: (NSString*) dockIconName
{ 
 NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

 NSDictionary* dockDict = [userDefaults persistentDomainForName:@"com.apple.dock"];

 NSMutableArray* apps = [dockDict valueForKey:@"persistent-apps"];
 if (apps != nil)
 { 
  NSArray* appsCopy = [apps copy];
  bool modified = NO;
  for(NSDictionary *anApp in appsCopy)
  {
   NSDictionary* fileDict = [anApp valueForKey:@"tile-data"];
   if(fileDict != nil)
   {
    NSString *appName = [fileDict valueForKey:@"file-label"];

    if([dockIconLabel isEqualToString:appName])
    {
     [apps removeObject:anApp];
     modified = YES;
     break;
    }
   }
  }
  if(modified)
  {
   //If the dictionary was modified, save the new settings.
   [userDefaults setPersistentDomain:dockDict forName:@"com.apple.dock"];
   //Reset the standardUserDefaults so that the modified data gets synchronized
   //and next time when this function is invoked, we get the up-to-date dock icon details.
   [NSUserDefaults resetStandardUserDefaults];
  }
 }
}


NOTE: It is a sample code written when I didn't have access to my Mac. Please do the necessary cleanup and fix syntax errors if any.
UPDATE: dockutil now has the fix for this issue. https://github.com/kcrawford/dockutil

Friday, 10 January 2014

Take awesome screenshots on Mac

Well, do you know Mac offers some really easy ways of capturing full or parts of its screen. Just with the click of some buttons, you can get the screenshot of a window, the full screen or just some part of the screen.
Pictures of the screen (screenshots) are saved as files on the desktop, but if you prefer to put a screenshot in the Clipboard, hold down the Control key while you press the other keys. You can then paste the picture into a document.
ActionShortcut
Take a picture of the whole screen
Command (⌘)-Shift-3
Take a picture of part of the screen
Command (⌘)-Shift-4, and then drag the crosshair pointer to select the area. Continue to press the mouse button, release the keys, and then press Shift, Option, or the Space bar while you drag to resize the selection area. When you are ready to take a picture, release the mouse button.
To cancel, press Escape before you release the mouse button.
Take a picture of a window or the menu bar
Command (⌘)-Shift-4, press the Space bar, move the camera pointer over the area to highlight it, and then click.
To cancel, press Escape before you click.
Take a picture of a menu, including the title
Click the menu to display the menu commands, press Command (⌘)-Shift-4, and drag the crosshair pointer over the area.
To cancel, press Escape before you click.
Take a picture of the menu without its title
Click the menu to display the menu commands, press Command (⌘)-Shift-4, press the Space Bar, move the camera pointer over the menu to highlight it, and then click.
To cancel, press Escape before you click.