<?xml version="1.0"?><!-- RSS generated by Radio UserLand v8.0.7 on Mon, 01 Apr 2002 16:27:50 GMT --><rss version="0.92">	<channel>		<title>Bill Bumgarner: Code</title>		<link>http://radio.weblogs.com/0100490/categories/code/</link>		<description>Code snippets.</description>		<copyright>Copyright 2002 Bill Bumgarner</copyright>		<lastBuildDate>Mon, 01 Apr 2002 16:27:50 GMT</lastBuildDate>		<docs>http://backend.userland.com/rss092</docs>		<managingEditor>bbum@codefab.com</managingEditor>		<webMaster>bbum@codefab.com</webMaster>		<cloud domain="radio.xmlstoragesystem.com" port="80" path="/RPC2" registerProcedure="xmlStorageSystem.rssPleaseNotify" protocol="xml-rpc"/>		<item>			<link>http://radio.weblogs.com/0100490/categories/code/2002/02/26.html#a120</link>			<description>&lt;h3&gt;Including Frameworks in your Application&lt;/h3&gt;Apple recommends that any frameworks required by your application be distributed within the app wrapper of the application itself.  Doing so is not 100% straightforward (and I couldn&apos;t find decent documentation on the subject).I was recently faced with the need to distribute the &lt;a href=&quot;http://www.mulle-kybernetik.com/&quot;&gt;Mulle Kybernetik&lt;/a&gt; XML-RPC frameworks inside of the application wrapper of the &lt;a href=&quot;http://radio.weblogs.com/0100490/categories/radioCommentary/&quot;&gt;RadioService&lt;/a&gt; application.What follows is a step by step description of what I did.  The end result works fine for both deployment and development;  development does require that you build the frameworks such that their *.framework product is present in the build products directory.   My build products preference is set to /tmp/bbum-products/.  This should not affect the overall solution.  In any case, it is generally a good idea to set the intermediate and product Build Results preferences to point to some location in /tmp/, preferably two different locations.  It is faster than working against a mounted drive (if your home directory is mounted) and doesn&apos;t clutter up the project directory with a bunch of files that should not be revision controlled.&lt;b&gt;Modifying the Framework project(s)&lt;/b&gt;&lt;ul&gt;&lt;li&gt;Add a new build style named &lt;b&gt;Embedded&lt;/b&gt;.&lt;/li&gt;&lt;li&gt;Set the following three variables:&lt;pre&gt;COPY_PHASE_STRIP = YESFRAMEWORK_INSTALLED_NAME = @executable_path$(/)..$(/)Frameworks$(/)$(PRODUCT_NAME).$(WRAPPER_EXTENSION)$(/)Versions$(/)$(FRAMEWORK_VERSION)$(/)$(PRODUCT_NAME)INSTALL_PATH = $(LOCAL_LIBRARY_DIR)/EmbeddedFrameworks&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Build &amp; Install the framework from the Terminal:&lt;pre&gt;pbxbuild -target &lt;target&gt; -buildstyle Embedded install DSTROOT=&lt;/pre&gt;(Replace &apos;&lt;target&gt;&apos; with the name of the target that builds the framework in your project)&lt;/li&gt;&lt;/ul&gt;You might need to either execute the pbxbuild step via sudo or create the /Library/EmbeddedFrameworks directory and change permissions on it accordingly.&lt;b&gt;Modifying the Application project(s)&lt;/b&gt;&lt;ul&gt;&lt;li&gt;Add the framework(s) from /Library/EmbeddedFrameworks to the project as you would any other framework.  PB will likely default to using an absolute path reference;  this is fine.&lt;/li&gt;&lt;li&gt;Add a &lt;i&gt;Copy Files&lt;/i&gt; build phase to the target that builds the application.&lt;/li&gt;&lt;li&gt;Add the frameworks to the new &lt;i&gt;Copy Files&lt;/i&gt; build phase.&lt;/li&gt;&lt;li&gt;Check the &apos;Copy only when installing&apos; checkbox.&lt;/li&gt;&lt;/ul&gt;When in active development, you will need to build the framework(s) via project builder as normal because the application will need to find them in your build-products directory at runtime.  This also ensures that the frameworks have debugging symbols, making debugging that much easier.For deployment, simply install the application as you normally would.  Typically, that would involve invoking something like...&lt;pre&gt;pbxbuild -buildstyle Deployment install DSTROOT=/tmp/MyApplication&lt;pre&gt;... from the terminal.The end result will be an application that should contain the frameworks within the application wrapper.  To test, do something like the following:&lt;pre&gt;[localhost:sourceforge/mosxland/RadioService] bbum% pbxbuild -buildstyle Deployment install[localhost:sourceforge/mosxland/RadioService] bbum% cd /tmp/RadioService.dst/RadioService.app/[localhost:bbum/Applications/RadioService.app] bbum% ls Contents/Frameworks/EDCommon.framework XMLRPC.framework[localhost:bbum/Applications/RadioService.app] bbum% otool -L Contents/MacOS/RadioService Contents/MacOS/RadioService:        /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 7.0.0)        /System/Library/Frameworks/Carbon.framework/Versions/A/Carbon (compatibility version 2.0.0, current version 122.0.0)        @executable_path/../Frameworks/EDCommon.framework/Versions/A/EDCommon (compatibility version 25.0.0, current version 28.0.0)        @executable_path/../Frameworks/XMLRPC.framework/Versions/A/XMLRPC (compatibility version 1.0.0, current version 1.0.0)        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 55.0.0)&lt;/pre&gt;</description>			</item>		<item>			<link>http://radio.weblogs.com/0100490/categories/code/2002/02/08.html#a27</link>			<description>&lt;table&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;[&lt;/b&gt;Macro error: Can&apos;t evaluate the expression because the name &quot;33853792&quot; hasn&apos;t been defined.&lt;b&gt;]&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;http://www.sbook5.com/&quot;&gt;SBook&lt;/a&gt; was the best address book ever.  Unlike every other address book, SBook didn&apos;t force entries to conform to some set of fields.  Instead, you simply typed whatever you wanted into an entry and SBook would take care of parsing out phone numbers, addresses, and email addresses (this was before the web).  The best part was the search-- you simply started typing into the search field and SBook would refine/update the match list in real time.   While it was written for the 68040 NeXT the matching and parsing functionality was incredibly fast-- realtime.&lt;a href=&quot;http://www.sbook5.com/&quot;&gt;SBook&lt;/a&gt; is coming to OS X!! Same great speed, same great verstility.  An alpha version can be downloaded from the &lt;a href=&quot;http://www.sbook5.com/&quot;&gt;SBook5 web site&lt;/a&gt;.&lt;a href=&quot;http://www.codefab.com/&quot;&gt;CodeFab&lt;/a&gt; has long had a web based contact manager;  very convenient when you have access to the net, but completely useless when on the road and without a net connection.  We have long had the ability to export to a text file, but sorting through hundreds of entries to find the right one could be tedious.Turns out that SBook can import an XML document of a very simple format.  What follows is a hunk of Java code that uses the &lt;a href=&quot;http://www.jdom.org/&quot;&gt;JDOM&lt;/a&gt; API to produce content that is stuffed into an HTTP response.   The resulting XML doc can be directly imported into SBook.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=2&gt;&lt;pre&gt;import org.jdom.*;import org.jdom.output.*;&lt;a href=&quot;//&quot;&gt;//&lt;/a&gt;public class SBookExporter {&lt;a href=&quot;//&quot;&gt;//&lt;/a&gt; this is copied directly from a WebObjects app.  Converting it to non-WebObjects&lt;a href=&quot;//&quot;&gt;//&lt;/a&gt; should be trivial;  there is no magic here.&lt;a href=&quot;//&quot;&gt;//&lt;/a&gt; Contact:  class containing your contact-- implement asSingleLargeString() to&lt;a href=&quot;//&quot;&gt;//&lt;/a&gt;     return a text representation of the contact.&lt;a href=&quot;//&quot;&gt;//&lt;/a&gt; This would have *some* whitespace, but Radio triple spaces if I do so...&lt;a href=&quot;//&quot;&gt;//&lt;/a&gt;    NSArray contactsToExport;&lt;a href=&quot;//&quot;&gt;//&lt;/a&gt;    public WOResponse generateResponse() {        if ( (contactsToExport == null) || (contactsToExport.count() == 0) )            return null;&lt;a href=&quot;//&quot;&gt;//&lt;/a&gt;                WOResponse xmlResponse = new WOResponse();&lt;a href=&quot;//&quot;&gt;//&lt;/a&gt;        xmlResponse.setStatus(200);        xmlResponse.setContent( generateDOMResponse() );        xmlResponse.setHeader(&quot;Content-type&quot;, &quot;text/xml&quot;);&lt;a href=&quot;//&quot;&gt;//&lt;/a&gt;        return xmlResponse;    }&lt;a href=&quot;//&quot;&gt;//&lt;/a&gt;    public String generateDOMResponse() {        return new XMLOutputter().outputString( generateJDOMResponse() );    }&lt;a href=&quot;//&quot;&gt;//&lt;/a&gt;    public org.jdom.Document generateJDOMResponse() {        Element rootElement = new Element( &quot;entries&quot; );        Enumeration contactEnumerator = contactsToExport.objectEnumerator();        DocType docType = new DocType(&quot;plist&quot;, &quot;SYSTEM&quot;, &quot;http://www.simson.net/sbook/sbook.dtd&quot;);        Contact nextContact;&lt;a href=&quot;//&quot;&gt;//&lt;/a&gt;        while (contactEnumerator.hasMoreElements()) {            nextContact = (Contact) contactEnumerator.nextElement();            Element entryElement = new Element( &quot;entry&quot; );            Element contactElement = new Element( &quot;text&quot; );            contactElement.addContent( nextContact.asSingleLargeString() );            entryElement.addContent(contactElement);            rootElement.addContent(entryElement);        }&lt;a href=&quot;//&quot;&gt;//&lt;/a&gt;        return new org.jdom.Document(rootElement, docType);    }}&lt;/pre&gt;</description>			</item>		<item>			<link>http://radio.weblogs.com/0100490/categories/code/2002/02/08.html#a26</link>			<description>I created a new category called &lt;a href=&quot;http://radio.weblogs.com/0100490/categories/code/&quot;&gt;Code&lt;/a&gt; to contain bits of code that some may find useful, interesting, or painfully stupid.  Some will be OS X specific, some WebObjects specific, and some totally generic;  Java, Python, ObjC, Lisp...</description>			</item>		</channel>	</rss>
