Posting arbitrary messages to any receiver



+ (id)sendToDelegate:(id)receiver message:(SEL)message arg1:(id)arg1, ...
{
   if (![receiver respondsToSelector:message])
   {
      @throw [NSException exceptionWithName:@"DelegaterException"
                   reason:[NSString stringWithFormat:@"Receiver doesn't respond to message %s",
                              sel_getName(message)]
                 userInfo:nil];
   }

   NSMethodSignature* sign = [receiver methodSignatureForSelector:message];
   NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:sign];
   [invocation setSelector:message];
   [invocation setTarget:receiver];
   [invocation setArgument:&arg1 atIndex:2];

   id arg;
   va_list args;
   va_start(args, arg1);
   int i = 3;
   while (arg = va_arg(args, id))
   {
      [invocation setArgument:&arg atIndex:i++];
   }
   va_end(args);

   [invocation invoke];
   id result;
   [invocation getReturnValue:&result];

   return result;
}
Advertisements

Adding SOAP Header in Java

Simple minimal code to add your own SOAP header



// Security	token
String token;
// MyService and MySoapService are stubs generated from WSDL
MyService service = new MyService();
MyServiceSoap ep = service.getMyServiceSoap();

Binding binding = ((BindingProvider) ep).getBinding();
List handlers = binding.getHandlerChain();
handlers.add(new MySOAPHandler(token));
binding.setHandlerChain(handlers);

Here is the code of the MySOAPHandler class used to intercept messages and actually add SOAP header



public class MySOAPHandler implements SOAPHandler {

	private String token;

	public DHSOAPHandler(String token) {
		this.token = token;
	}
	public boolean handleMessage(SOAPMessageContext messageContext) {
		SOAPMessage
		msg = messageContext.getMessage();
		if ((Boolean) messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY)){
			try {
				SOAPEnvelope envelope = msg.getSOAPPart().getEnvelope();
				SOAPHeader header = envelope.addHeader();
				SOAPElement el = header.addHeaderElement(envelope.createName("TicketHeader",
									"", "http://ws.service.com/"));
				el = el.addChildElement(envelope.createName("Ticket", "", "http://ws.service.com/"));
				el.setValue(token);
				msg.saveChanges();
			}
			catch (SOAPException	e) {
				return false;
			}
		}
		return true;
	}

	public boolean handleFault(SOAPMessageContext messageContext) {
		return true;
	} 

	public void close(MessageContext messageContext){
	}
	// I'm not quite sure about what should this function do, but I guess something like this...
	public Set getHeaders(){
		Set headers = new HashSet();
		headers.add(new QName("https://ws.service.com/", "TicketHeader"));
		return headers;
	}
}

The structure of the header to be added is



<TicketHeader>
	<Ticket>OD01096347CCA</Ticket>
</TicketHeader>

Cocoa Event Handling


Some extracts from Apple Developer’s Manuals which are important for me. That helps me to understand how I could respond to definite event in my application.
A responder is an object that can receive events, either directly or through the responder chain, by virtue of its inheritance from the NSResponder class. NSApplication, NSWindow, NSDrawer, NSWindowController, NSView and the many descendants of these classes in the Application Kit inherit from NSResponder.
If we take a look at the following list we’ll see that not only NSResponder descendants could actually respond to that messages.

  1. The main window’s first responder and the successive responder objects up the view hierarchy
  2. The main window itself
  3. The main window’s delegate (which need not inherit from NSResponder)
  4. The application object, NSApp
  5. The application object’s delegate (which need not inherit from NSResponder)

Connecting custom controller instance of a class, derived from NSObject (or other class not rooted to NSResponder) class to NSWindow‘s or NSApplication‘s (NSApp) delegate outlet also puts controller object into FirstResponder chain.
Keep in mind sequence of responders in the chain when deciding which class should contain responding method.

Creating unit tests in XCode

Add unit test target

  • Select Targets group and select Add|New Target…|Unit Test Bundle
  • Setup dependent test bundle
    • Double-click test unit target to display it’s info. Select General tab and add project to be tested to dependencies
    • Select Build tab and set Bundle Loader value to $(BUILT_PRODUCTS_DIR)/MyApp.app/Contents/MacOS/MyApp
      if you are testing application and to $(BUILT_PRODUCTS_DIR)/MyApp if you are testing framework. Set Test Host value to $(BUNDLE_LOADER)

Debugging unit tests

Mostly this is taken from Chris Hanson’s blog but contains one adjustment

When you add the custom executable, Xcode will bring up its info window. Switch to the Arguments tab. Here you’ll need to enter some command-line arguments to pass to the test rig and some environment variables to affect how it’s run. In the arguments tab of your application executable, first add an environment variable named DYLD_INSERT_LIBRARIES. Set its value to $(SYSTEM_LIBRARY_DIR)/PrivateFrameworks/DevToolsBundleInjection.framework/DevToolsBundleInjection . Then add a second environment variable, XCInjectBundle. Set its value to MyTestBundle.octest . (Originally, it was $(BUILT_PRODUCTS_DIR)/MyTestBundle.octest but that didn’t work for me. See this answer for details). Make sure the check marks next to both of these environment variables — and your -SenTest All argument, of course — are set.

To actually debug a failing test, build your tests and set a breakpoint on the line where the failure occurs. Now choose Debug Executable from the Debug menu. Do not choose Build and Debug from the Build menu. You need to use Debug Executable because your build will fail due to the failing test; Debug Executable doesn’t try to build first, it only cares whether an executable is present.

You should successfully stop at your breakpoint!

If your tests take a long time to run — they shouldn’t, they’re unit tests after all, but it can still happen — you may want to just run the tests for one test case, or just one individual test. This is easy too. Rather than specifying -SenTest All in your arguments to otest, you can specify -SenTest MyTestCaseClassName to run the all the tests in the specified test case. To run just a single test, use -SenTest MyTestCaseClassName/testMethodName instead.

References:
http://www.stiefels.net/2007/05/01/unit-testing-with-xcode
http://chanson.livejournal.com/119578.html

Cocoa memory management

Here is extraction of simple memory management rules for Cocoa Framework

The important things to remember about memory management in Cocoa distill down to these rules of thumb:

  • Objects created by alloc or copy have a retain count of 1.
  • Assume that objects obtained by any other method have a retain count of 1 and reside in the autorelease pool. If you want to keep it beyond the current scope of execution, then you must retain it.
  • When you add an object to a collection, it is retained. When you remove an object from a collection, it is released. Releasing a collection object (such as an NSArray) releases all objects stored in it as well.
  • Make sure that there are as many release or autorelease messages sent to objects as there are alloc, copy, mutableCopy, or retain messages sent. In other words, make sure that the code you write is balanced.
  • Retain, then release objects in setter methods.
  • NSString objects created using the @" . . . " construct are effectively constants in the program. Sending retain or release messages to them has no effect. This explains why we haven’t been releasing the strings created with the @" . . . " construct.

References
http://www.stepwise.com/Articles/Technical/2001-03-11.01.html
http://www.oreillynet.com/pub/a/mac/excerpt/Cocoa_ch04/index.html