<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Cappuccino Blog &#187; CPURLConnection</title>
	<atom:link href="http://cappuccino.org/discuss/tag/cpurlconnection/feed/" rel="self" type="application/rss+xml" />
	<link>http://cappuccino.org/discuss</link>
	<description>Home of Cappuccino and Objective-J</description>
	<lastBuildDate>Thu, 17 Nov 2011 00:42:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>XMLHTTPRequest, JSONP &amp; Cappuccino</title>
		<link>http://cappuccino.org/discuss/2008/10/08/xmlhttprequest-jsonp-cappuccino/</link>
		<comments>http://cappuccino.org/discuss/2008/10/08/xmlhttprequest-jsonp-cappuccino/#comments</comments>
		<pubDate>Wed, 08 Oct 2008 07:53:08 +0000</pubDate>
		<dc:creator>ross</dc:creator>
				<category><![CDATA[Cappuccino]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[CPURLConnection]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[XMLHTTPRequest]]></category>

		<guid isPermaLink="false">http://cappuccino.org/discuss/?p=56</guid>
		<description><![CDATA[If you&#8217;re a veteran web developer, you&#8217;re probably familiar with the XMLHTTPRequest (XHR for short), the bread and butter of &#8220;AJAX&#8221;. XHRs are what make dynamic applications that don&#8217;t reload the page possible. For an application framework like Cappuccino this is critical, since Cappuccino applications are designed to never reload the page &#8212; so it&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re a veteran web developer, you&#8217;re probably familiar with the XMLHTTPRequest (XHR for short), the bread and butter of &#8220;AJAX&#8221;. XHRs are what make dynamic applications that don&#8217;t reload the page possible. For an application framework like Cappuccino this is critical, since Cappuccino applications are designed to never reload the page &#8212; so it&#8217;s important to understand exactly how Cappuccino deals with these requests.</p>
<p>Before we get in too deep, a quick primer on exactly what I&#8217;m talking about. If you&#8217;re comfortable with XMLHTTPRequests already, feel free to skip this paragraph. <a href="http://en.wikipedia.org/wiki/XMLHttpRequest">XMLHTTPRequest</a> was introduced by Microsoft in Internet Exporer 5 as a way for scripts within a web page to send a remote request to another server without reloading the entire page. Although it started as a propriety Microsoft technology, it was later adopted by Mozilla, and eventually all the other major browsers. The term AJAX, which stands for Asynchronous JavaScript and XML, is essentially synonymous with the use of XMLHTTPRequests on a website. A website creates an XHR object with a specific URL, gives it a function to execute when the status of the request changes, and then executes the request. With this mechanism, your script can use most of the HTTP verbs, and can respond to specific HTTP response codes, which makes it a flexible and powerful API. If you&#8217;re coming from Cocoa, or another desktop programming environment, you may be used to classes that perform similar functions like NSURLConnection or maybe even (approximately) curl and wget. There are, however, important limitations introduced by the browser security model that we&#8217;ll discuss shortly.</p>
<h3>XMLHTTPRequest</h3>
<p>In Objective-J and Cappuccino, asynchronous http requests are instrumental for creating a working app, beginning with the import statement. As you&#8217;ve probably noticed by now, Objective-J introduces the <strong class="keyword">import</strong> keyword to JavaScript. Import statements pull in and execute Objective-J code at runtime, which lets us maintain dependency relationships across classes in Cappuccino, much like code in C or Java. These statements are actually asynchronous, and are implemented using XHRs. This means we only have to include one script tag in our <em>index.html</em> file for Objective-J only, while the rest of Cappuccino is bootstrapped with these asynchronous requests. This is a fairly low level detail, but it illustrates the importance of the XHR when writing complex javascript based applications.</p>
<p>When writing a Cappuccino applications, XHRs are the primary way to communicate with your backend server. While most of your application logic may be running in the client, certain tasks will still need to run on a webserver.  For example, consider an authentication system; in order for authentication to be meaningful, it will need to present credentials to a server for verification. Similarly, features like persistent data storage require server communication to actually store the data, otherwise it would dissappear when the user navigated away from the page. To put it another way, if your app doesn&#8217;t talk to an outside server, it may be of limited utility.</p>
<h3>CPURLConnection</h3>
<p>Like most things in Cappuccino, XMLHTTPRequests are abstracted at a higher level. In this case, the CPURLConnection class manages the communication. If we look at the <a href="http://cappuccino.org/learn/documentation/class_c_p_u_r_l_connection.html">API Reference</a>, we&#8217;ll find a few different ways to create an instance. The easiest way is the class method <strong class="keyword">connectionWithRequest:delegate:</strong>, which takes a CPURLRequest object and a delegate. CPURLRequest objects wrap a single request, including the URL, HTTP method, request body, and request headers. Like everywhere in Cappuccino, the delegate provides for the ability to customize the request&#8217;s behavior. Let&#8217;s look at the process of creating a CPURLConnection.</p>
<pre class="enscript" ><!--BEGIN enscript-->var request = [CPURLRequest requestWithURL:<B><span style="color:#BC8F8F">&quot;list.txt&quot;</span></B>];
var connection = [CPURLConnection connectionWithRequest:request delegate:<B><span style="color:#A020F0">self</span></B>];<!--END enscript--></pre>
<p>As you can see, it&#8217;s a simple process. Connections created with this class method fire immediately, without needing to explicitly call any additional methods.  By default, the request object will be a GET request, with no additional data. Like any URL on a webpage, the URL will be treated as relative to your <em>index.html</em> file unless you specify an absolute path or URL (e.g. preceding the URL with http://). To handle the response, we can implement these two optional delegate methods:</p>
<pre class="enscript" ><!--BEGIN enscript-->
- (<B><span style="color:#228B22">void</span></B>)<B><span style="color:#0000FF">connection</span></B>:(<B><span style="color:#228B22">CPURLConnection</span></B>) <span style="color:#B8860B">connection</span> <B><span style="color:#0000FF">didReceiveData</span></B>:(<B><span style="color:#228B22">CPString</span></B>)<span style="color:#B8860B">data</span>
{
    <I><span style="color:#B22222">//This method is called when a connection receives a response. in a
</span></I>    <I><span style="color:#B22222">//multi-part request, this method will (eventually) be called multiple times,
</span></I>    <I><span style="color:#B22222">//once for each part in the response.
</span></I>}

- (<B><span style="color:#228B22">void</span></B>)<B><span style="color:#0000FF">connection</span></B>:(<B><span style="color:#228B22">CPURLConnection</span></B>)<span style="color:#B8860B">connection</span> <B><span style="color:#0000FF">didFailWithError</span></B>:(<B><span style="color:#228B22">CPString</span></B>)<span style="color:#B8860B">error</span>
{
    <I><span style="color:#B22222">//This method is called if the request fails for any reason.
</span></I>}<!--END enscript--></pre>
<p>After your request is created it will be fired, and later CPURLConnection will call the methods above on the connection&#8217;s delegate. These methods are both optional, but are the minimum that you should implement in order to interact with your AJAX requests. The first is essential in processing any response, and the second is necessary for correctly dealing with errors, which is an important part of a well written application. Let&#8217;s look at a real world implementation of these two methods, as well as the creation of a request, to get a sense for how all this works.</p>
<p>The following code is taken from 280 Slides. It deletes a photo from your library. In this first chunk, we&#8217;ll construct and start our connection:</p>
<pre class="enscript" ><!--BEGIN enscript-->
<I><span style="color:#B22222">//BASE_URL is a 280 Slides global, which points to the base directory of our server structure
</span></I>var request = [CPURLRequest requestWithURL: BASE_URL+<B><span style="color:#BC8F8F">&quot;Media/photo.php?id=&quot;</span></B>+itemID];

<I><span style="color:#B22222">//we're using HTTP verbs to keep our backend as RESTful as possible
</span></I>[request setHTTPMethod: <B><span style="color:#BC8F8F">&quot;DELETE&quot;</span></B>];

<I><span style="color:#B22222">//create the CPURLConnection and store it. the connection fires immediately
</span></I>_deletePhotoConnection = [CPURLConnection connectionWithRequest: request delegate: <B><span style="color:#A020F0">self</span></B>];<!--END enscript--></pre>
<p>Notice that we store a reference to the connection in the ivar <em>_deletePhotoConnection</em>. This is so, if we have multiple connections, we can check to ensure we&#8217;re responding to the right one. Now let&#8217;s look at the delegate method implementations:</p>
<pre class="enscript" ><!--BEGIN enscript-->
- (<B><span style="color:#228B22">void</span></B>)<B><span style="color:#0000FF">connection</span></B>:(<B><span style="color:#228B22">CPURLConnection</span></B>)<span style="color:#B8860B">aConnection</span> <B><span style="color:#0000FF">didReceiveData</span></B>:(<B><span style="color:#228B22">CPString</span></B>)<span style="color:#B8860B">data</span>
{
    <I><span style="color:#B22222">//get a javascript object from the json response
</span></I>    var result = CPJSObjectCreateWithJSON(data);

    <I><span style="color:#B22222">//check if we're talking about the delete connection
</span></I>    <B><span style="color:#A020F0">if</span></B> (aConnection == _deletePhotoConnection)
        [<B><span style="color:#A020F0">self</span></B> deletePhoto:result.<B><span style="color:#A020F0">id</span></B>];   <I><span style="color:#B22222">//deletes the specified photo
</span></I>
    <I><span style="color:#B22222">//clear out this connection's reference
</span></I>    [<B><span style="color:#A020F0">self</span></B> clearConnection:aConnection];
}

- (<B><span style="color:#228B22">void</span></B>)<B><span style="color:#0000FF">connection</span></B>:(<B><span style="color:#228B22">CPURLConnection</span></B>)<span style="color:#B8860B">aConnection</span> <B><span style="color:#0000FF">didFailWithError</span></B>:(<B><span style="color:#228B22">CPError</span></B>)<span style="color:#B8860B">anError</span>
{
    <B><span style="color:#A020F0">if</span></B> (aConnection == _deletePhotoConnection)
        alert(<B><span style="color:#BC8F8F">&quot;There was an error deleting this photo. Please try again in a moment.&quot;</span></B>);

    [<B><span style="color:#A020F0">self</span></B> clearConnection:aConnection];
}

- (<B><span style="color:#228B22">void</span></B>)<B><span style="color:#0000FF">clearConnection</span></B>:(<B><span style="color:#228B22">CPURLConnection</span></B>)<span style="color:#B8860B">aConnection</span>
{
    <I><span style="color:#B22222">//we no longer need to hold on to a reference to this connection
</span></I>    <B><span style="color:#A020F0">if</span></B> (aConnection == _deletePhotoConnection)
        _deletePhotoConnection = <B><span style="color:#A020F0">nil</span></B>;
}<!--END enscript--></pre>
<p>Again, the code is very simple. Since we send and receive data using JSON, the first call in our <strong>connection:didReceiveData:</strong> implementation turns that text response (<em>data</em>) into a javascript object using the JSON helper function <strong>CPJSObjectCreateWithJSON()</strong>. For the reverse operation, you can use the reverse function, <strong>CPJSObjectCreateJSON()</strong>. With the resulting object in hand, we check if the resulting connection is in fact our _deletePhotoConnection, and if it is, we proceed to delete the photo referenced in the object. In the alternate case, where our request is unsuccessful, we prompt the user to inform them that the request failed and do not delete the photo.</p>
<p>You&#8217;ll notice that both methods call <strong>clearConnection:</strong>. This is a convenience method we&#8217;ve written to nil out our reference to the connection object once we&#8217;ve finished using it. Although not strictly necessary, keeping a pointer to the object means it won&#8217;t be collected by the garbage collector. Removing the reference from our instance variable is the best practice since we know we will not be using it again. </p>
<p>Although it&#8217;s not shown here, the reason we store a reference to the specific connection is that we use other connections in the same class, so we need a simple way to tell them apart. If you&#8217;re only using one connection with your delegate, you may not need to use this technique or store a reference to the connection at all.</p>
<p>Finally, there are two additional CPURLConnection delegate methods we chose not to implement, but which you may be interested in for your own application. There&#8217;s also a class delegate for handling request authentication at the application level. You can read more about these methods in the <a href="http://cappuccino.org/learn/documentation/class_c_p_u_r_l_connection.html">API documentation</a>. </p>
<h3>CPJSONPConnection</h3>
<p>One of the limitations of the XHR is that it must follow what is known in the web security world as the <a href="http://en.wikipedia.org/wiki/Same_origin_policy">same origin policy</a>. The model requires that requests can only be sent to URLs with the same protocol, domain, and port number as the web page. This policy makes it difficult to interact with third party web services without having to proxy requests first through your own webserver.  Several people developed their own workarounds to the limitation, but eventually <a href="http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/">JSONP</a> emerged as the standard mechanism. </p>
<p>JSONP stands for JSON with Padding, and it comprises two components. The first part deals with getting around the same origin policy itself. XMLHTTPRequests may not work across multiple domains, but &lt;script&gt; tags have no such limitation. JSONP takes advantage of this by  dynamically generating a &lt;script&gt; tag and appending it to the page. The script&#8217;s src property is set to the URL of the remote API, including all request parameters in the query string. The second component of JSONP deals with what to do once the API returns a response.</p>
<p>As the name suggests, JSONP APIs return their data in the JSON format, but instead of returning a plain JSON string, they wrap the JSON response in a function call. This extra function call is the &#8220;padding&#8221; in JSONP, and it effectively works around the browser&#8217;s security policy. Typically, function name is a parameter of the request, which you can see demonstrated in the Flickr API.  This API allows you to specify <em>format=json</em> to get a JSON response, and <em>jsoncallback=myfunctionname</em> to specify your custom function wrapper for the response. An example request might look something like this:</p>
<pre class="enscript" ><!--BEGIN enscript-->
<B><span style="color:#A020F0">var</span></B> url = <B><span style="color:#BC8F8F">&quot;http://www.flickr.com/services/rest/&quot;</span></B>+
          <B><span style="color:#BC8F8F">&quot;?method=flickr.interestingness.getList&quot;</span></B>+
          <B><span style="color:#BC8F8F">&quot;&amp;format=json&amp;jsoncallback=flickResponse&amp;api_key=YOUR_KEY&quot;</span></B>;<!--END enscript--></pre>
<p>As you can imagine, generating your own dynamic script tags and managing global callback methods would be a serious hassle, which is why Cappuccino has built in support in the form of <a href="http://cappuccino.org/learn/documentation/class_c_p_j_s_o_n_p_connection.html">CPJSONPConnection</a>. You may have encountered this class in the source of our <a href="http://cappuccino.org/learn/demos/FlickrPhotoDemo/">Flickr Demo</a>. Creating an instance should look familiar:</p>
<pre class="enscript" ><!--BEGIN enscript-->
var connection = [CPJSONPConnection sendRequest:aRequest callback:aCallbackParameter delegate:<B><span style="color:#A020F0">self</span></B>];<!--END enscript--></pre>
<p>The additional parameter, <strong>callback:</strong>, is a string that specifies the name of the parameter that allows us to specify the callback function&#8217;s name in the JSONP API we&#8217;re talking to. Similar to CPURLConnection, these two delegate methods are defined:</p>
<pre class="enscript" ><!--BEGIN enscript-->
- (<B><span style="color:#228B22">void</span></B>)<B><span style="color:#0000FF">connection</span></B>:(<B><span style="color:#228B22">CPJSONPConnection</span></B>)<span style="color:#B8860B">aConnection</span> <B><span style="color:#0000FF">didReceiveData</span></B>:(<B><span style="color:#228B22">Object</span></B>)<span style="color:#B8860B">data</span>
{
    <I><span style="color:#B22222">//called by the &quot;padding&quot; function when the request is complete
</span></I>
    <I><span style="color:#B22222">//depending on the third part API, data may be the native javascript object,
</span></I>    <I><span style="color:#B22222">//or it may be a string. usually a js object is used, but if a string
</span></I>    <I><span style="color:#B22222">//is passed, you can create a js object with CPJSObjectCreateWithJSON()
</span></I>}

- (<B><span style="color:#228B22">void</span></B>)<B><span style="color:#0000FF">connection</span></B>:(<B><span style="color:#228B22">CPJSONPConnection</span></B>)<span style="color:#B8860B">aConnection</span> <B><span style="color:#0000FF">didFailWithError</span></B>:(<B><span style="color:#228B22">CPString</span></B>)<span style="color:#B8860B">error</span>
{
    <I><span style="color:#B22222">//will be called if the connection fails
</span></I>    <I><span style="color:#B22222">//will see improvements in an upcoming release
</span></I>}<!--END enscript--></pre>
<p>Let&#8217;s take a look at the actual implementation in our Flickr Demo:</p>
<pre class="enscript" ><!--BEGIN enscript-->
- (<B><span style="color:#228B22">void</span></B>)<B><span style="color:#0000FF">applicationDidFinishLaunching</span></B>
{
    ...

    <I><span style="color:#B22222">//Create the request, which contains all of our query parameters,
</span></I>    <I><span style="color:#B22222">//except the jsoncallback parameter
</span></I>
    var req = [CPURLRequest requestWithURL:
                    <B><span style="color:#BC8F8F">&quot;http://www.flickr.com/services/rest/&quot;</span></B>+
                    <B><span style="color:#BC8F8F">&quot;?method=flickr.interestingness.getList&quot;</span></B>+
                    <B><span style="color:#BC8F8F">&quot;&amp;per_page=20&amp;format=json&amp;api_key=&quot;</span></B>+API_KEY];

    <I><span style="color:#B22222">//Create the connection, set the callback, and make ourselves the delegate.
</span></I>    <I><span style="color:#B22222">//the connection fires immediately
</span></I>
    var connection = [CPJSONPConnection sendRequest:req callback:<B><span style="color:#BC8F8F">&quot;jsoncallback&quot;</span></B> delegate:<B><span style="color:#A020F0">self</span></B>];
}

- (<B><span style="color:#228B22">void</span></B>)<B><span style="color:#0000FF">connection</span></B>:(<B><span style="color:#228B22">CPJSONPConnection</span></B>)<span style="color:#B8860B">aConnection</span> <B><span style="color:#0000FF">didReceiveData</span></B>:(<B><span style="color:#228B22">Object</span></B>)<span style="color:#B8860B">data</span>
{
    <I><span style="color:#B22222">//the response from Flickr is the actual JS Object, which has an
</span></I>    <I><span style="color:#B22222">//array of photos that we pass to our collection view
</span></I>    [<B><span style="color:#A020F0">self</span></B> addImageList:data.photos.photo withIdentifier: lastIdentifier];
}

- (<B><span style="color:#228B22">void</span></B>)<B><span style="color:#0000FF">connection</span></B>:(<B><span style="color:#228B22">CPJSONPConnection</span></B>)<span style="color:#B8860B">aConnection</span> <B><span style="color:#0000FF">didFailWithError</span></B>:(<B><span style="color:#228B22">CPString</span></B>)<span style="color:#B8860B">error</span>
{
    <I><span style="color:#B22222">//Ideally, we would do something smarter here.
</span></I>    alert(error);
}<!--END enscript--></pre>
<p>Due to the use of the script tag injection, as opposed to a traditional XHR object, we don&#8217;t have any fine grained information about the response. We cannot detect status codes, and cannot natively access the response. Thankfully, CPJSONPConnection does a good job of managing the additional complexity, and massaging it into a familiar API. There is still some work to be done on generating more reliable errors, but it should be completed in the near future.</p>
<p>JSONP does have it&#8217;s own security implications. Because you&#8217;re essentially allowing arbitrary third party code to execute within the context of your own application, you should only use JSONP with providers you trust. It&#8217;s also important to note that because these requests are sent to different domains, cookies from your own site will not be sent along with the request. This prevents third parties from stealing your sessions, but it also means that authenticating requests is significantly more complex.</p>
<h3>Conclusion</h3>
<p>There&#8217;s been some confusion about when to use CPURLConnection versus CPJSONPConnection, due largely in part to the lack of documentation or discussion on the issue. In general, you should only use JSONP with third-party services that you trust, and only when doing so doesn&#8217;t involve sensitive information. For example, getting public Flickr photos, or performing a Google search using Google&#8217;s AJAX search API. If you&#8217;re communicating with your own service, even if you use JSON as the transmission format, you should use CPURLConnection. Their are numerous advantages to this approach, especially the additional security. </p>
<p>I hope this has illustrated both when and how to use CPURLConnection and CPJSONPConnection. As we continue to develop Cappuccino, we&#8217;ll be improving both of these classes, and introducing new communication methods as well. If you have questions, sound off in the comments, or try the <a href="http://cappuccino.org/discuss/list.php">mailing list or irc channel</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://cappuccino.org/discuss/2008/10/08/xmlhttprequest-jsonp-cappuccino/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
	</channel>
</rss>

