<?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>Undefined Function</title>
	<atom:link href="http://undefinedfunction.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://undefinedfunction.org</link>
	<description></description>
	<lastBuildDate>Tue, 01 Nov 2011 21:54:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>InstantChat is Live on the App Store</title>
		<link>http://undefinedfunction.org/2010/12/instantchat-is-live-on-the-app-store/</link>
		<comments>http://undefinedfunction.org/2010/12/instantchat-is-live-on-the-app-store/#comments</comments>
		<pubDate>Mon, 20 Dec 2010 02:28:10 +0000</pubDate>
		<dc:creator>Michael Jones</dc:creator>
				<category><![CDATA[Apps]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Mobile]]></category>

		<guid isPermaLink="false">http://undefinedfunction.org/?p=101</guid>
		<description><![CDATA[A pet project of mine, InstantChat, went live on the App Store today. It&#8217;s a (very) simple chat app that lets you quickly connect and chat with any nearby iPhone, iPod touch, or iPad via Bluetooth. I&#8217;m planning on adding some more features in the near future, such as Wi-Fi connectivity, chat history logging, and [...]]]></description>
			<content:encoded><![CDATA[<p>A pet project of mine, InstantChat, went live on the App Store today. It&#8217;s a (very) simple chat app that lets you quickly connect and chat with any nearby iPhone, iPod touch, or iPad via Bluetooth. I&#8217;m planning on adding some more features in the near future, such as Wi-Fi connectivity, chat history logging, and a few other goodies.</p>
<p>Feel free to try it out, and let me know what you think!<br />
<a href="itms://itunes.apple.com/us/app/instantchat/id386888824?mt=8" title="Available on the App Store"><img class="size-full wp-image-102" title="Available on the App Store" src="http://undefinedfunction.org/wp-content/uploads/2010/12/AppStore.png" alt="Available on the App Store" width="200" height="100" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://undefinedfunction.org/2010/12/instantchat-is-live-on-the-app-store/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why You Should Care About UI</title>
		<link>http://undefinedfunction.org/2010/12/why-you-should-care-about-ui/</link>
		<comments>http://undefinedfunction.org/2010/12/why-you-should-care-about-ui/#comments</comments>
		<pubDate>Sun, 12 Dec 2010 11:58:04 +0000</pubDate>
		<dc:creator>Michael Jones</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://undefinedfunction.org/?p=84</guid>
		<description><![CDATA[I know a lot of developers aren&#8217;t great with UI design, or &#8220;making it look pretty&#8221; as some will call it, but too often it seems that making necessary improvements to the interface of an application or site is the subject of procrastination &#8212; &#8220;we&#8217;ll get to it when we have time&#8221; &#8212; and then [...]]]></description>
			<content:encoded><![CDATA[<p>I know a lot of developers aren&#8217;t great with UI design, or &#8220;making it look pretty&#8221; as some will call it, but too often it seems that making necessary improvements to the interface of an application or site is the subject of procrastination &#8212; &#8220;we&#8217;ll get to it when we have time&#8221; &#8212; and then time never arrives, as many other things are considered more important. Even when a company has a full-time designer, it seems that the designer often has the struggle of selling people on their cause before they can get significant changes made, because developers often feel it isn&#8217;t important to make the requested changes if the site already works, although the user&#8217;s experience may be suboptimal.</p>
<p>I have seen this many times, and often it is even further shadowed by the fact that the product or site is popular with its customers, or that people have used it for a long time, so it must be fine, right? Wrong. Just because people are buying or using your product doesn&#8217;t mean there aren&#8217;t problems with it, or that it doesn&#8217;t need improvement. And you can&#8217;t always rely on the customer to tell you what they want to see in terms of UI, because they often don&#8217;t know &#8212; they just want it to work with the least amount of effort necessary.</p>
<p>This is the concept that is important to keep in mind when developing the application as well, as many complex applications have complex UIs that are completely necessary. It is often assumed that flexibility requires complexity, but there are many good examples that this is not the case. A good working example would be the file search feature in Apple&#8217;s Mac OS X Finder.</p>
<div id="attachment_85" class="wp-caption aligncenter" style="width: 310px"><a href="http://undefinedfunction.org/wp-content/uploads/2010/12/Screen-shot-2010-12-13-at-3.07.59-AM.png"><img src="http://undefinedfunction.org/wp-content/uploads/2010/12/Screen-shot-2010-12-13-at-3.07.59-AM-300x138.png" alt="" title="Search Options in Mac OS X Finder" width="300" height="138" class="size-medium wp-image-85" /></a><p class="wp-caption-text">Search Options in Mac OS X Finder</p></div>
<p>Rather than bombarding the user with every possible option, they are initially presented with a simple search field, present at the corner of every file window. Typing in that field will initiate a quick search for files that match the entered text, and the toolbar shows just a couple of options, allowing the user to specify if they want to search the entire computer or just their folder, and if they want to show all files that contain the text, or just ones whose names match. Clicking the plus sign to the right offers an additional row, allowing the user to further refine the search by selecting a property and a condition (i.e. &#8220;Kind&#8221; is &#8220;PDF&#8221; or &#8220;Name&#8221; &#8220;begins with&#8221; &#8220;Agreement&#8221;). The user can then continue adding these filters to obtain as much detail as they need. While the display can become cluttered with several of these filter bars, it is not as confusing or overwhelming as the countless and little used search boxes may be on some &#8220;advanced&#8221; searching interfaces, where the user must look through a wide array of fields to determine which fields require input to filter results.</p>
<p>It is this mindset of keeping UI elements simple and relevant to the user that is necessary for sites and applications to thrive. If your interface is clean, simple and functional, not only will users buy your product or service and continue to use it, but they will actually enjoy using it and be more likely to offer positive recommendations to others because they enjoy it. </p>
]]></content:encoded>
			<wfw:commentRss>http://undefinedfunction.org/2010/12/why-you-should-care-about-ui/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Magic Methods to Call Remote Functions</title>
		<link>http://undefinedfunction.org/2010/11/remotely-execute-functions/</link>
		<comments>http://undefinedfunction.org/2010/11/remotely-execute-functions/#comments</comments>
		<pubDate>Sat, 27 Nov 2010 14:43:30 +0000</pubDate>
		<dc:creator>Michael Jones</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://undefinedfunction.org/?p=82</guid>
		<description><![CDATA[Have you ever wanted to directly call a function or method that is in a script on another server? I know it sounds crazy, but stay with me here. Initially, my answer to this solution was to write an XML interface, which seemed entirely logical especially since both sides of the equation weren&#8217;t necessarily running [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever wanted to directly call a function or method that is in a script on another server? I know it sounds crazy, but stay with me here. Initially, my answer to this solution was to write an XML interface, which seemed entirely logical especially since both sides of the equation weren&#8217;t necessarily running in PHP. </p>
<p>So to execute a service on another machine, the front-end server would have an object definition, which would both provide a defined structure for the object (such as a payment), as well as offering some common methods to perform a remote request to the backend server to actually do some work. When the object was ready to do something, it would call its own request method, passing in a URL to an interface page, and the request method would handle building an XML request based on the properties of the object, posting the XML to the page that was passed in, and then returning the XML response when all was done. On the other side of the picture, the page that is handling the request would in turn initialize a similarly structured object, which was defined with the necessary methods to perform the work requested (such as processing a payment).  For example, in order to call the MakePayment method on the payment object, the frontend would need a MakePayment method, which sets up the payment details and initiates the XML request, and then the XML interface would need a handler created to set up the payment and handle calling the MakePayment method on the actual object on the backend server.</p>
<p>Definitely not the most elegant solution, but it made the most sense when we originally encountered the need to pass requests between servers, particularly due to the language differences I mentioned earlier. </p>
<p>Some of the best and craziest ideas happen by chance, and that&#8217;s exactly how I stumbled upon this idea. A coworker was having some difficulty with one of the services, and was slightly confused by which code was causing the problem, as there were effectively four components in the mix &#8212; the display page on the frontend, the service&#8217;s object definition, the XML interface on the backend server, and the &#8220;real&#8221; object definition there. After seeing the error he was getting and having a look at the code, I determined the problem was that he was just missing a method definition on the frontend, and would need to create one. When I explained this, however, he responded with a simple question: &#8220;Why can&#8217;t I just call this method directly?&#8221;  My initial response, of course, was to say &#8220;because it&#8217;s on another server&#8221; and that you can&#8217;t simply make calls across systems like that, but then I started wondering exactly the same thing &#8212; why not?</p>
<p>I knew that you could transfer information across systems easily by storing session data in a shared database, and I started to wonder why a similar principle wouldn&#8217;t work for directly calling methods. So the solution I came up with is actually relatively simple: serialize the request object and send the entire object over the POST to the other server. The handler on that server just needs to unserialize it there, and call the requested method, and then serialize and return the response.  I further simplified this by defining a __call &#8220;magic method&#8221; on the template object that automatically facilitates the request, allowing you to call any method that is defined on the backend server&#8217;s object in the code on the frontend without having to define the methods on both servers.</p>
<p>There are, of course, some gotchas to watch out for (some objects can&#8217;t be easily serialized, such as SimpleXMLElements), but for the most part this works pretty well and requires very little code to function on the frontend server.</p>
]]></content:encoded>
			<wfw:commentRss>http://undefinedfunction.org/2010/11/remotely-execute-functions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple IP Address &amp; Subnetting Class</title>
		<link>http://undefinedfunction.org/2009/10/simple-ip-address-subnetting-class/</link>
		<comments>http://undefinedfunction.org/2009/10/simple-ip-address-subnetting-class/#comments</comments>
		<pubDate>Mon, 05 Oct 2009 00:30:48 +0000</pubDate>
		<dc:creator>Michael Jones</dc:creator>
				<category><![CDATA[Networking]]></category>

		<guid isPermaLink="false">http://undefinedfunction.org/?p=13</guid>
		<description><![CDATA[On a few occasions, I&#8217;ve been faced with situations where I&#8217;ve needed to determine whether a given IP address was part of a particular subnet. Granted, usually PHP sites don&#8217;t need to worry about things like that, but sometimes it is necessary to restrict access to users in certain locations, or maybe you want a [...]]]></description>
			<content:encoded><![CDATA[<p>On a few occasions, I&#8217;ve been faced with situations where I&#8217;ve needed to determine whether a given IP address was part of a particular subnet. Granted, usually PHP sites don&#8217;t need to worry about things like that, but sometimes it is necessary to restrict access to users in certain locations, or maybe you want a reporting tool to be able to filter by a range of IPs when you click on an individual address.</p>
<p>To accomplish these tasks, I have written a couple of classes that are intended to simplify things. Rather than completely reinventing the wheel, I started with the excellent open source SubnetCalc project by Ramond Ferguson. I adapted the existing code into an object-oriented class structure, and updated the regular expression handling to use the superior preg_* functions to improve speed and future compatibility, as ereg has been deprecated. In addition to the detailed subnet calculation functions already offered by the project, I have added a few new features:</p>
<ul>
<li>Test if a given IP is a valid address</li>
<li>Determine IP type (node, network, or broadcast) based on the associated subnet schema</li>
<li>Test whether an IP is within in the subnet&#8217;s address range</li>
<li>Dynamically alter the subnet schema &#8212; calculations are automatically updated to the new values</li>
</ul>
<p>They always say the proof is in the pudding, so here are a couple of usage examples. First, let&#8217;s create an IP object. The class will automatically test to see that the IP is valid, and throw an exception if it&#8217;s not:</p>
<div class='code'>
<div class='title'>Create an IP object</div>
<pre>try {
	$ip = new IPAddress('192.168.1.12');
} catch( Exception $e ) {
	print $e;
}</pre>
</div>
<p>To assign a subnet mask, you can call the SetCIDR method:</p>
<div class='code'>
<div class='title'>Configure the subnet using SetCIDR</div>
<pre>$ip->Subnet->SetCIDR(24);</pre>
</div>
<p>And now your object is populated with a handful of useful calculations:</p>
<div class='code'>
<div class='title'>Output of the IPAddress object</div>
<pre>IPAddress Object
(
    [Address] => 192.168.1.12
    [Subnet] => Subnet Object
        (
            [Class] => C
            [Netmask] => 255.255.255.0
            [CIDR] => 24
            [Wildcard] => 0.0.0.255
            [Network] => 192.168.1.0
            [Broadcast] => 192.168.1.255
            [FirstHost] => 192.168.1.1
            [LastHost] => 192.168.1.254
            [Hosts] => 254
            [Private] => 1
        )

)</pre>
</div>
<p>You can also use the Subnet object by itself to perform simple calculations without a specific IP address, and you can call the IsValidHost() method to test an IP address to see if it fits in the subnet. An example of how this might look:</p>
<div class='code'>
<div class='title'>Working With Subnets</div>
<pre>try {
	$subnet = new Subnet("192.168.1.0/27");
        print $subnet->IsValidHost("192.168.1.21") ? "YES" : "NO";
        print $subnet->IsValidHost("192.168.1.64") ? "YES" : "NO";
} catch( Exception $e ) {
	print $e;
}</pre>
</div>
<p>In this example, a subnet is created, with possible hosts from 192.168.1.1 to 192.168.1.30. So the first print statement would display &#8220;YES&#8221;, since node 21 falls within the subnet, and the second statement would display &#8220;NO&#8221;, as node 64 is not part of the subnet.</p>
<p>If you would like to try these out for yourself, you can <a href='http://scripts.undefinedfunction.org/downloads/phpiplib-1.0.tar.gz'>download the classes here</a>. Thus far, the class seems to work well for my purposes, but as this is based on some unfamiliar code from another project, I could have easily missed something. I will continue to fine tune the code, and will be doing some minor cleanup on the imported functions as time permits, so be sure to check back periodically for any updates.</p>
]]></content:encoded>
			<wfw:commentRss>http://undefinedfunction.org/2009/10/simple-ip-address-subnetting-class/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Yay for power outages</title>
		<link>http://undefinedfunction.org/2009/08/yay-for-power-outages/</link>
		<comments>http://undefinedfunction.org/2009/08/yay-for-power-outages/#comments</comments>
		<pubDate>Thu, 06 Aug 2009 23:19:51 +0000</pubDate>
		<dc:creator>Michael Jones</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://undefinedfunction.org/?p=11</guid>
		<description><![CDATA[I love unexpected power outages, especially when they last for hours and prevent me from getting work done. So, if you couldn&#8217;t reach some of my less important sites, including this one, that&#8217;s why.]]></description>
			<content:encoded><![CDATA[<p>I love unexpected power outages, especially when they last for hours and prevent me from getting work done. So, if you couldn&#8217;t reach some of my less important sites, including this one, that&#8217;s why.</p>
]]></content:encoded>
			<wfw:commentRss>http://undefinedfunction.org/2009/08/yay-for-power-outages/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apple and the App Store</title>
		<link>http://undefinedfunction.org/2009/07/apple-and-the-app-store/</link>
		<comments>http://undefinedfunction.org/2009/07/apple-and-the-app-store/#comments</comments>
		<pubDate>Sat, 01 Aug 2009 01:30:49 +0000</pubDate>
		<dc:creator>Michael Jones</dc:creator>
				<category><![CDATA[Apple]]></category>

		<guid isPermaLink="false">http://undefinedfunction.org/?p=9</guid>
		<description><![CDATA[I&#8217;ve had a very interesting response to my recent TUAW article regarding the removal of Google Voice from the App Store. Reader &#8220;VanillaSpice&#8221; gave some good insight into his opinion of the whole ordeal, and I think it&#8217;s worth reposting our exchange here: The way refunds are handled is explained (very clearly) in the developer [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve had a very interesting response to my recent TUAW article regarding the removal of Google Voice from the App Store. Reader &#8220;VanillaSpice&#8221; gave some good insight into his opinion of the whole ordeal, and I think it&#8217;s worth reposting our exchange here:</p>
<blockquote><p>The way refunds are handled is explained (very clearly) in the developer agreement, and each developer signs and agrees to that agreement. What you don&#8217;t do is, knowingly sign a contract and then complain about the terms. What you DO do is, don&#8217;t sign the contract at all if you don&#8217;t like it.</p>
<p>Every developer knew &#8211; before they signed &#8211; that the refund process meant they could be refunding more than 100% of their revenue. Their only two options &#8211; complain and don&#8217;t sign, or sign and don&#8217;t complain. Those who sign and complain have only themselves to blame, they KNOWINGLY signed up to this deal!</p></blockquote>
<p>Actually, if I remember correctly, for many developers the refund option didn&#8217;t even exist initially, and many developers were upset when it appeared in a later update to the agreement.</p>
<p>Either way, it&#8217;s a good point, since developers pretty much do agree to those terms just like many consumers agree to ridiculous terms on credit cards, and then complain when they are hit with huge fees because they didn&#8217;t actually read what they were agreeing to. And in this case, it&#8217;s no fault of Apple&#8217;s if the dev didn&#8217;t read their agreement. Luckily, in most cases, it doesn&#8217;t appear that Apple enforces it anyways.</p>
<blockquote><p>I do believe, personally, that users should only ever get from the developers the amount the devs have actually been paid, and no more, but then, I didn&#8217;t sign the agreement, hey.</p>
<p>&#8220;And yes, there are over 10,000 developers, 65,000 apps, 40 million devices, and 1 billion downloads from the App Store. But none of that matters unless you realize that the developers themselves are directly responsible for much of the iPhone&#8217;s success. By alienating those developers through inconsistent policy handling and refusal to communicate one-on-one with them to resolve problems, Apple is setting itself up for failure.&#8221;</p>
<p>I disagree with this. I think it *does* matter that 10,000 devs have made 65,000 apps without much hassle, and yet the number of rejections and complaints is &#8230; what? A dozen? A few dozen?</p></blockquote>
<p>Okay, I could have used better wording instead of saying &#8220;It doesn&#8217;t matter,&#8221; but I think you underestimate the number of rejections and complaints that actually happen. Yes, when compared to the total number of 65,000 apps, even saying as many as maybe (just throwing a number out there) 5,000 of those apps were rejected seems insignificant.</p>
<p>But looking at it from a different angle, we here at TUAW get a good number of e-mails regarding apps that were rejected or complaints about the approval process on a DAILY basis. Yeah, some are repeats and some days are more than others, but still, there is a much larger volume of rejections and complaints than what actually gets covered in the media.</p>
<blockquote><p>I think it is very important for you to put things in context, otherwise you are misrepresenting the true situation &#8211; you&#8217;ve basically made it sound, from the article, that all developers have a problem with Apple, when in fact, we&#8217;ve only heard that a dozen or so do (out of 10,000 &#8211; that is a very small percentage!)</p></blockquote>
<p>Agreed. But what I believe the real problem is doesn&#8217;t lie in the number of developers affected, as much as in the significance of the problems those developers have faced.</p>
<p>If it were just a handful of devs getting apps rejected for blatantly violating terms of the SDK, I don&#8217;t think there&#8217;d really be much to complain about, and we wouldn&#8217;t be having this discussion. But what&#8217;s happening is individual developers hit snags with Apple, where they follow all of the rules but, for one reason or another, Apple removes/rejects their app or some other problem arises that makes everyone stop and wonder what is going on.</p>
<p>And it is here that Apple stumbles, because they don&#8217;t deal with the problem in an efficient manner, they usually either give vague, inconsistent responses to the developer, or they choose not to communicate at all. Then the developer gets upset, the media gets involved and it becomes a big PR nightmare, and only then does Apple (sometimes) step in and make an attempt to remedy the situation. But by that time, the damage is already done.</p>
<blockquote><p>I also disagree with the overall tone of the article which suggests that Apple benefits from developers while developers do not benefit from Apple at all.</p></blockquote>
<p>That&#8217;s not the tone I intended, so I apologize if that&#8217;s what you&#8217;re getting from it. The intention was to express and convey the frustration with Apple&#8217;s decision to pull the GV apps, and claim that they were &#8220;duplicating functionality&#8221; rather than being open and honest with developers about the true reasons for their removal and offering methods of recourse; their lack of communication to the parties involved when they encountered the problem; and the effects of penalizing the developers with refunds for a decision that really was not the developer&#8217;s fault.</p>
<blockquote><p>No developer designed, created and marketed the iPhone and App Store. That was Apple. But developers have been able to use this new market to make money &#8211; we know that some devs have profited (and profited well) from the App Store. So I think it is abundantly clear that devs have benefited from Apple as well as the reverse.</p></blockquote>
<p>Completely agree.</p>
<blockquote><p>Lastly, I don&#8217;t agree that Apple is setting themselves up for failure &#8211; I remember similar comments about Nintendo abandoning the polygon count race, and we know how that turned out.</p>
<p>Sometimes, decisions that look wrong on first glance, turn out to be right. This has been true of Apple in the past. It was wrong for Apple to launch a smartphone without copy-and-paste, without multitasking, without a replaceable battery, wasn&#8217;t it? More like 40 million points of right. Apple correctly identified what people wanted and needed, while most everyone else fell over themselves declaring that Apple had set themselves up for failure.</p></blockquote>
<p>This can be interpreted very differently, depending on how you define failure. Do I think that the App Store will collapse, killing the viability of the iPhone platform and destroy the future of Apple? Definitely not. But I think that it is reasonable to believe the App Store (and by effect, Apple) could ultimately be less successful as a result of these problems. Sure, they might have achieved their goal to create a viable platform that allows developers to easily create apps and users to easily find those apps, but the attitude they choose to use when interacting with developers and dealing with problems harbors more dissent and unwelcome feelings among the community, which has proven to be detrimental to many platforms over the years.</p>
<blockquote><p>I think you are discounting how much the iPhone&#8217;s and iPod Touch&#8217;s stability and friendliness comes from Apple&#8217;s &#8220;crazy&#8221; rules and the heavy-handed imposition of them, and I think you are blatantly assuming that Apple has had no reason to ever pull and reject apps. Apple might not be saying, but that does not mean that they don&#8217;t have a reason and that it isn&#8217;t a good one.</p></blockquote>
<p>Valid points, though I don&#8217;t assume that Apple has had no reason to pull or reject apps. My contention lies in the fact that they hide their reasons behind vague and inconsistent policies. If you&#8217;re going to reject application X for having a particular feature, then you need to reject applications Y and Z if they have the exact same feature. To me, it&#8217;s fine if they have to pull an app from the store, but they need to take the developer of the app aside, and explain to them exactly why it is being pulled, and what options of recourse they might have to prevent it (if the pulling is due to a specific element of the application).</p>
<p>I mean, seriously, the developer is already under an NDA, so just remind them that under the terms of that NDA, they cannot disclose the reason the app was pulled to the public, and take them to court if they leak the details. And, if for some reason Apple simply *can&#8217;t* disclose to the developer their reasoning, don&#8217;t hide behind a vague claim that is obviously untrue, but instead tell the developer outright that they are unable to disclose the details, and then offer an olive branch to them by suggesting some form of recourse or compensation or *something* for the trouble.</p>
<p>But yeah, I agree that they might have reasons that they are not willing to discuss. And if they are going somewhere with those reasons, that&#8217;s fine. But they still need to keep an open line of communication to the developers. Even if that just means someone calling them up or sending a personal e-mail an saying something like this:</p>
<p>&#8220;Look, I&#8217;m really sorry, but we have to pull your app from the store. You didn&#8217;t do anything wrong, but we have to remove it for technical reasons. I&#8217;m afraid I can&#8217;t go into details at this time, but we will do our best to let you know if and when it can be resubmitted. I realize that you have put a lot of time and effort into this application, and due to the circumstances, we are willing to offer you ________________. In exchange, we ask you to keep the terms of this arrangement confidential, please inform users that the application had to be removed due to technical difficulties. In the event that refunds are requested, we will work with you on those cases.&#8221;</p>
<p>To me, a simple conversation like that would go A LONG WAY to keeping good spirits about the situation. Yes, it would still be a bit frustrating, but at least you&#8217;d have the feeling that *someone* at Apple actually cared, which unfortunately, doesn&#8217;t seem to be the case with many of these stories.</p>
<p>Ok, I&#8217;m done now. <img src='http://undefinedfunction.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://undefinedfunction.org/2009/07/apple-and-the-app-store/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simplify Reporting Output</title>
		<link>http://undefinedfunction.org/2009/03/simplify-reporting-output/</link>
		<comments>http://undefinedfunction.org/2009/03/simplify-reporting-output/#comments</comments>
		<pubDate>Wed, 18 Mar 2009 05:16:47 +0000</pubDate>
		<dc:creator>Michael Jones</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://undefinedfunction.org/?p=4</guid>
		<description><![CDATA[Recently, I have been tasked having to generate several reports containing various metrics, and then export these into an Excel sheet so that the data can be processed further. I also occasionally get requests for data in a CSV format that can be imported into another system. And these are just for the one-off reports&#8230; [...]]]></description>
			<content:encoded><![CDATA[<div id="_mcePaste">Recently, I have been tasked having to generate several reports containing various metrics, and then export these into an Excel sheet so that the data can be processed further.  I also occasionally get requests for data in a CSV format that can be imported into another system.  And these are just for the one-off reports&#8230; most of the standard reporting tools I have written produce data in an XML format, which is then procssed by an AJAX frontend and displayed in an HTML table to the user.  Talk about messy.</div>
<div id="_mcePaste">So this morning, I finally sat down and wrote out a report abstraction class that has been floating around in my head for the past couple of months.  Rather than have to worry about writing display code when building a report, I can simply deal with the data and hand it over to the class for display processing:</div>
<div class='code'>
<div class='title'>Building the Report Class</div>
<pre>
$Report = new Report( "My Report" );<br />
if (isset($_GET['format'])) {<br />
$Report->Type = $_GET['format'];<br />
}<br />
$Report->Columns = array("Employee", "Department", "Salary");<br />
foreach ($Employees as $Employee) {<br />
$Report->Rows[] = array($Employee->Name, $Employee->Department, $Employee->Salary);<br />
}<br />
$Report->Display();
</div>
<div style="text-align: left;">From there, the class takes the type identifier (which in this case is being selected by the user and passed in the URL), and provides the data in the correct format.  The class itself is fairly small, weighing in with less than 200 lines of code, but can display data in Excel, CSV, XML, HTML, or PDF, as well as a printer-optimized layout if the data is intended to be printed instead of displayed on-screen.</div>
<p>Recently, I have been tasked having to generate several reports containing various metrics, and then export these into an Excel sheet so that the data can be processed further.  I also occasionally get requests for data in a CSV format that can be imported into another system.  And these are just for the one-off reports... most of the standard reporting tools I have written produce data in an XML format, which is then procssed by an AJAX frontend and displayed in an HTML table to the user.  Talk about messy.<br />
So this morning, I finally sat down and wrote out a report abstraction class that has been floating around in my head for the past couple of months.  Rather than have to worry about writing display code when building a report, I can simply deal with the data and hand it over to the class for display processing:</p>
<div class='code'>
<div class='title'>Displaying a Report</div>
<pre>
$Report = new Report( "My Report" );<br />
if (isset($_GET['format'])) {<br />
                 $Report->Type = $_GET['format'];<br />
        }</p>
<p>$Report->Columns = array("Employee", "Department", "Salary");<br />
        foreach ($Employees as $Employee) {<br />
                $Report->Rows[] = array($Employee->Name, $Employee->Department, $Employee->Salary);<br />
        }<br />
$Report->Display();
</p></div>
<p>From there, the class takes the type identifier (which in this case is being selected by the user and passed in the URL), and provides the data in the correct format.  The class itself is fairly small, weighing in with less than 200 lines of code, but can display data in Excel, CSV, XML, HTML, or PDF, as well as a printer-optimized layout if the data is intended to be printed instead of displayed on-screen.</p>
]]></content:encoded>
			<wfw:commentRss>http://undefinedfunction.org/2009/03/simplify-reporting-output/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

