i3Factory World

Your Iphone, iPad & Android Application Factory

Browsing Posts published in February, 2012

Two different concepts

In our previous article on the subject we explained how to create an app that supports the Newsstand feature introduced by Apple with iOS 5. The concepts explained in that post provide the technical references needed to build an app that is able to retrieve and download any new content, even in the background, and update the cover-like icon in the Newsstand app. Unfortunately while technically an app build in this way is completely functional, it wouldn’t be approved by Apple if sent for review. The reason for this is that Apple requires that each app compatible with Newsstand must offer its contens using an iTunes managed subscription.

Subscriptions are a rather new concept. They have been initially introduced with iOS 4 but their support has been greatly improved by Apple after a long discussion taken with publishers in order to build a business model acceptable for everybody. In particular the subscription concept has been enlarged by adding auto-renewable subscriptions and with the introduction of Newsstand – and its concept of issues auto-download – also free subcriptions have been added.

Before entering in the detail I would to emphasize the fact that one of the most interesting features of Newsstand, that is background auto-downloading of a new newspaper or magazine issue, is triggered by the special push notification I talked about in the previous part of this tutorial. The In App Purchase concepts are related to auto-download but there is no relation at all, from coding point of view, between the two concepts. As soon as the pubsliher has some new content, he can push this information to the application passing the content-available message together will all info required by the app to start automatic download. The In App Purchase subscriptions concept enters in this scheme from the publisher side by answering a simple question: “did the user subscribe to receive new content from us”? This means that the publisher is not allowed to push any new content to the user if he didn’t previously subscribed. That’s why Apple requires that each Newsstand application is paired with a corresponding In App Subcription service: because the customer must explicitly request for getting automatically the content (even if for free) and at the same time they want to reduce extra bandwith and device resources usage if the contents are not required.

Adding your Newsstand In App Purchases

I will not enter in a detailed explanation of how to setup your application for In App Purchase. This is well explained in Apple’s iTunesConnect Developer Guide and In App Purchase Programming Guide. I strictly recommend you read these guides, especially the second one, and exercise your developer account by creating a test app on iTunesAccount. In any case it is worth to summarize the main steps:

  • Enter in your application page inside the iTunesConnect portal and click on the Manage In-App Purchases button
  • For each type of subscription you want to setup, generate a specific In App Purchase product. In the following picture you can see that I listed three possible choices: one free subscription (note that free subscriptions don’t expire) and two auto-renewable subcriptions, both linked to the same product but with different duration and price.
  • Generate a shared secret and take note of it. You will need it later.
  • Note that the portal page has another sections called Newsstand. It will be used by the App Store only for marketing purposes and allows the publisher to keep his App Store page uptodate with the latest cover, consider for example the iTunes link of the New Yorker app: you will see the latest cover displayed instead of the app icon. An extra option given by Apple is the possibility to link this page to a Newsstand Atom Feed URL for automatic update. We’ll not talk anymore about this option in this tutorial.

A free subscription doesn’t require much data to be inserted: as it is an In App Purchase product, you must provide a unique product identifier; recommended practice is to use the reverse DNS convention, e.g. com.viggiosoft.NewsstandTutorial.subscription.free is enough self explaining; you will also add a display name (that is a title for the subscription) and a description, both localized. Auto-renewable subscriptions are a bit more complex. Infact when you define a subscription you will define a sort of reference product container that will open a family of similar In App Purchase products: this is an In App Purchase product that will not contain any reference to the duration of the subscription and will be used as a base for the single durations. This means that immediately after you have added your reference product, specifying its ID (still in reverse DNS), display name, description and publication name (all localized), you will be asked to add each specific product ID linked to the required duration: one week, one month, and so on up to one year. Note that the display name and description of these sub-products is taken directly from their reference, so the only information that you will be required to add is the duration, the price and of course the unique product ID.

Once this task has been accomplished, you can finally exit iTunesConnect and enter in the XCode domain.

Store Kit implementation

In our simple implementation we can imagine the app as in part I where we added three extra subscription buttons. Note that we are not implementing here any server-side capability, we’ll give some hints at the end and the app will emulate a basic receipt validation mechanism only for the purpose of completeness. The first button will allow the user to subscribe for free to a specific set of magazines. The other two options will ask the user to subscribe to the two one-month and one-year auto-renewable offers that we previously defined in iTunesConnect. Technically we are doing in all three cases a real In App Purchase transaction: in one case it will be free, in the other two cases a monetary transaction will occur.

Below you can see a set of snapshots taken from the app while used in the testing (sandbox) environment. You will notice that more or less the flow is the same of standard In App Purchase with a few noticeable differences:

  1. The title will change to Confirm Subscription
  2. Note that for the paid case, the 1 month term is automatically generated by the system based on the duration of the selected subscription. The only term customizable by the user is the Super Magazine Subscription definition that we set in iTunesConnect without any explicit reference to the duration.
  3. Immediately after the purchase, the system will ask for the explicit permission to send some personal data to the publisher. This is another compromise between Apple and the publishers that accepted to provide discounted subscriptions but in return of the possibility to control this kind of data (useful for advertising purposes).
  4. In case you already subscribed, the system will recall the user that he/she already subscribed and that the subsription will renew automatically at expiration. Read below to know how to avoid while developing the app to wait 1 month or 1 year to test your app after you did the first subscription…

At this point the code is not different from the usual code you may have written in the past. Let’s summarize here the main steps with the required code. For simplicity we have merged together the Store Kit communicationinside the main app view controller. Probably in a more complex application you want to separate the view controller from the store logic. As basic setup, don’t forget to link your code to the StoreKit library and import the framework header:

1
#import <StoreKit/StoreKit.h&gt> 

Besides our view controller will need to declare itself as conform to SKPaymentTransactionObserver, SKRequestDelegate and SKProductsRequestDelegate protocols. Finally our application delegate must register our view controller to be a transaction observer:

1
2
3
4
5
6
7
8
9
10
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // other initialization code goes here // in particular we assume our "store" view controller has been already initialized here // StoreKit transaction observer [[SKPaymentQueue defaultQueue] addTransactionObserver:self.store]; // other initialization code } 

Immediately after clicking on one of the subscription buttons, we’ll call a method that will start the purchase procedure (eventually updating the UI) based on the product ID we pass to it: what we do here is to use a variable called purchasing to avoid two or more purchase operations going together (note that In App Purchase is highly asynchronous with unpredictable delays and trying to place together more purchases would be messy for the user). Then we create our StoreKit product request and submit to the App Store:

1
2
3
4
5
6
7
8
9
10
- (IBAction)subscription:(NSString *)productId { if(purchasing_==YES) { return; } purchasing_=YES; // product request SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:productId]]; productsRequest.delegate=self; [productsRequest start]; } 

The request can fail, and in such case we reset our UI (not displayed here) and unset the purchasing flag. If the request succeeds, we’ll get the product IDs returned from the request and we’ll add them to the payment queue, effectively starting the operation. For completeness we should hilight the fact that in most cases the initial prouct request can be done independently on the effective user request of doing a purchase: the reason for this is that doing a product request is the only way to retrieve the exact product price localized to the user iTunes Store he’s currently connected. This means that we should never hard code a price in our app but we must retrieve it dynamically using a product request. In this case I simply skipped this extra step, not necessary for the purpose of the tutorial, by avoiding to mention any price in the subscription buttons! but be awave that showing the price together with a “buy” button is more than a welcome addition. Returning to our code, you will see below that we’ll loop through the returned responses (we shouldn’t get more than one due to the logic of the app) and for each of them we submit a payment request.

1
2
3
4
5
6
-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response { for(SKProduct *product in response.products) { SKPayment *payment = [SKPayment paymentWithProduct:product]; [[SKPaymentQueue defaultQueue] addPayment:payment]; } } 

As we previously registered this view controller instance as store kit transaction observer, we’ll get a few calls to the paymentQueue:updatedTransaction: protocol method. We must follow the right logic according to the effective state of the transaction. In our case we’re of course interested to the “success” case, managed via a call to our internal finishedTransaction: method:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { for(SKPaymentTransaction *transaction in transactions) { switch (transaction.transactionState) { case SKPaymentTransactionStateFailed: [self errorWithTransaction:transaction]; break; case SKPaymentTransactionStatePurchasing: break; case SKPaymentTransactionStatePurchased: case SKPaymentTransactionStateRestored: [self finishedTransaction:transaction]; break; default: break; } } } 

To terminate the transaction, we’ll inform the transaction queue that we declared our transaction finished. Now in a standard In App Purchase environment, based on typical consumable or non-consumable product, we should immediately provide the purchased product to the customer. For the subscription case infact we’re not providing a specific product but a subscription to a set of future products. Typically we’ll immediately unlock the access to the latest magazine (and as we’re in Newsstand doing this is quite easy…) but the most important stuff is that we must inform our server of the transaction data. The code below is a possible example of this, but we’ll explain the mechanism in more detail in the next paragraph. For the moment just notice that apart a few alerts displayed with some logging information we are sending the transaction receipt received from the store to a specific class called ReceiptCheck:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
-(void)finishedTransaction:(SKPaymentTransaction *)transaction { [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Subscription done" message:[NSString stringWithFormat:@"Receipt to be sent: %@\nTransaction ID: %@",transaction.transactionReceipt,transaction.transactionIdentifier] delegate:nil cancelButtonTitle:@"Close" otherButtonTitles:nil]; [alert show]; [alert release]; // save receipt [[NSUserDefaults standardUserDefaults] setObject:transaction.transactionIdentifier forKey:@"receipt"]; // check receipt [self checkReceipt:transaction.transactionReceipt]; } -(void)errorWithTransaction:(SKPaymentTransaction *)transaction { [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Subscription failure" message:[transaction.error localizedDescription] delegate:nil cancelButtonTitle:@"Close" otherButtonTitles:nil]; [alert show]; [alert release]; } -(void)checkReceipt:(NSData *)receipt { ReceiptCheck *checker = [ReceiptCheck validateReceiptWithData:receipt completionHandler:^(BOOL success,NSString *answer){ if(success==YES) { NSLog(@"Receipt has been validated: %@",answer); } else { NSLog(@"Receipt not validated! Error: %@",answer); }; [checker release]; }]; [checker retain]; } 

Server-side subscriptions management

We previously said that after a user completed a subscription purchase, we are not able to provide the full content immediately, but we still need to know when this content must be provided for the future. The current case is easily managed. If we call our 1-month subscription com.viggiosoft.NewsstandTutorial.subscription.1month then from the purchase receipt we know the purchase date and simply parsing the product ID we are able to define the expiration date as the transaction date + 1 month. This is easy and can be stored inside the app, at least for UI management. But there are many things that could happen in the subscription management and that the app is not necessarily aware: e.g. the subscription is renewed, or it has not been renewed by user choice, or it has not been renewed just because before the expiration we increased the price of our subscription (Apple stops any automatic renew in such event) or finally we defined a marketing bonus, that is provide e.g. 1 extra weekly subscription for each 1 month purchase (this is a possibility that is explicitly provided by iTunesConnect and is called marketing opt-in incentive. This means that a set of transactions may occur outside the control of the application: at this point the data we stored in the app immediately after the purchase couldn’t be reliable and we need to contact the App Store for the uptodate information. The best way to do this is to send the receipts to our server and let the server to systematically call Apple to maintain its subscription status for each user aligned with the App Store; in our case our app can simply use a basic API towards our server to lock or unlock certain magazines. But there is another reason why the server must take this information and it is strongly related to Newsstand: in order to push new content to the user device, the server must know for each new issue if the user is subscribed to it or not. So every time the publisher releases a new copy of his daily newspaper or a new issue of his weekly magazine, the subscription information of all users must be queried and the new content must be pushed to their device only if their subscription is still valid. Clearly we need to understand how this information is managed and can be retrieved.

In our example app we decided to implement a basis scheme of receipt validation directly inside the app. As we stated before, this is not the right method to do it and we simply added this extra code only for the needs of this tutorial. That’s why we decided to move this receipt validation scheme in an external class.

The end of the payment transaction is represented by an instance of the SKPaymentTransaction class which contains all the data required to keep track of the paymen: the ID of the purchased product, its quantity, the price paid, the date, a transaction identifier and most of important of all – for server based delivery of In App Purchases – the transaction receipt. This receipt is a chunk of data, internally coded by Apple, that can be decoded by sending an appropriate JSON message to iTunes’ receipt verification API (there are two different addresses, one for production and one for sandbox testing, see Apple documentation for a complete description of this API and the returned messages and error codes):

1
2
3
4
{ "receipt-data":"base64-data-encoding-of-receipt-data" "password":"your-autorenewable-shared-secret-from-itunesconnect" } 

In return Apple server will give us a full description of the receipt. A real example taken from the tutorial app of a possible receipt of the free subscription is shown below. .

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{ "status":0, "receipt":{ "bvrs":"1.0", "item_id":"473670104", "bid":"com.viggiosoft.tutorial.NewsstandTutorial", "product_id":"com.viggiosoft.tutorial.NewsstandTutorial.001", "purchase_date":"2011-10-29 19:49:02 Etc/GMT", "original_transaction_id":"1000000011535741", "quantity":"1", "original_purchase_date":"2011-10-29 17:14:33 Etc/GMT", "transaction_id":"1000000011544007" } } 

For a auto-renewable transaction the returned data contains more data. Initially you must check for the status key, if it is 0 then all went OK, if not 0 then you must understand the error message (the auto-renewable subscriptions possible status codes are summarized in Apple documentation). In addition you will get the expiration date (inclusive of the opt-in incentive) and the original transaction ID, that is the ID of the transaction that originated the subscription. In case the transaction has been auto-renewed and we are still sending to our server the original receipt, iTunes will return as an extra field, called latest_receipt_inf which will contain the latest renewed receipt together with the base64 version of this receipt. It makes sense in our case to replace our original receipt data with the latest one for the next queries.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{ "status":0, "receipt":{ "bvrs":"1.0", "item_id":"476937514", "bid":"com.viggiosoft.tutorial.NewsstandTutorial", "product_id":"com.viggiosoft.tutorial.NewsstandTutorial.1month", "purchase_date":"2011-10-29 20:30:07 Etc/GMT", "expires_date_formatted":"2011-10-29 20:35:07 Etc/GMT", "expires_date":"1319920507692", "quantity":"1", "original_transaction_id":"1000000011540367", "original_purchase_date":"2011-10-29 18:41:32 Etc/GMT", "transaction_id":"1000000011546189" }, "latest_receipt_info":{ "bvrs":"1.0", "item_id":"476937514", "bid":"com.viggiosoft.tutorial.NewsstandTutorial", "product_id":"com.viggiosoft.tutorial.NewsstandTutorial.1month", "purchase_date":"2011-10-29 20:30:07 Etc/GMT", "expires_date_formatted":"2011-10-29 20:35:07 Etc/GMT", "expires_date":"1319920507692", "quantity":"1", "original_transaction_id":"1000000011540367", "original_purchase_date":"2011-10-29 18:41:32 Etc/GMT", "transaction_id":"1000000011546189"}, "latest_receipt":"base64-encode-of-latest-receipt" } } 

As you can see the receipt doesn’t contain any reference to the Apple ID used to make the purchase. The only way for us to match the specific device with the returned receipt is to send to our server both the Apple Push token (APNS token) and store both in the same record of our server-side database. In this way when we have new content available to be pushed to our customer Newsstand we’ll be able to process all of our APNS tokens, check the receipts and if the new content (magazine or newsspaper) is still covered by the user subscription we’ll then send the Newsstand push notification to trigger the download on the user device.

What happens if the user wants to use the same subscription data in another device? in such case we must provide the typical transaction restore process as required by the Store Kit guidelines. Typically the restore button is placed somewhere in your application UI and his only purpose is to call this method:

1
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions]; 

All consumable and non-consumable transactions will be restored in the usual way: the SKPaymentTransactionStateRestored transaction update will be notified to our Store Kit observer and from the originalTransaction property of our SKPaymentTransaction we can get the product ID and then unlock it on the new device (don’t forget that the user can simply buy single issues from our app). For subscriptions the history is a little bit different, infact the system will return us the full set of transaction associated to the subscription history: infact each time a subscription is automatically renewed a new transaction is generated and it is stored in Apple servers. But why we need to know the whole history of user subscriptions? because as soon as we restore the subscription on a different device, we need to know for which dates the user was subscribed and only knowing the whole subscription history we’ll be able to unlock the right content: nothing more, nothing less than the user purchased for. Typically these receipt will be of the form explained above, that is a json message composed of the two fields: “receipt” and “latest_receipt_info”. The latter will all refer to the latest valid receipt, while the former will be different and related to each of the transactions: we must parse the purchase and expiration dates to create the valid subscription date range and provide the content accordingly.

Time compression

Before delivering our application we must carefully test all possible subscription cases: add a subscription, auto-renew, new content push notifications, subscription expiration, and so on. Clearly it would be impossible to wait for days or weeks or months to do these tests only. In Sandbox testing Apple compresses this time by giving you the possibility to test your application in minutes or hours. Looking at the receipts above, you will see that for a subscription purchased on Oct 29 at 20:30 (8:30 PM) there is a corresponding expiration date of only 5 minutes (same date at 20:35). This is because in the sandbox environment a 1 month subscription is compressed to a 5 minutes time scale. The full table of subscription duration / sandbox time scale is given in the figure. Besides auto-renewal will stop after 6 renewals thus giving you the possibility to manage the end-of subscription case (to avoid delivering content the user didn’t pay for): don’t forget that with a In App Purchase test account you cannot connect to the real iTunes store and so you have no way to manage subscriptions manually.

To better visualize this effect I added in my example application a “Receipts” button. After each purchase I store in a file the receipt data. When the user clicks this button, this file is opened and all stored receipts are sent to Apple for validation. The returned JSONs are then displayed as an alert. So if you try for example to purchase a 1 month subscription, and then immediately after the purchase you query for the receipts, you will get the purchase receipt only. Then try after 5/10 minutes (corresponding to 1 month in the time compression scale) to reopen the app and query for receipts again. The system will return you 2 or more receipts, each one corresponding to a different auto-renewal subscription: note the expiration date, it will be the same in the latest receipt field, but it will change in the receipt field as it is associated to each 1 month (5 minutes) renewal. Then close the app, wait for 40 minutes and try again: you will not get more than 6 receipts, as by convention after the 6th renewal attempt the subscription will automatically expire. You can improve this code by doing some real subscription date range detection and show it clearly to the user. Even more interesting is that as a transaction is automatically generated for each auto-renew, if you keep your app running in the foreground during an autorenewal, your app will be notified through the transaction observer mechanism and the receipt will be immediately validated.

Conclusions

This second part of the Newsstand Tutorial talks a bit of Newsstand and much more of In App Purchase and subscriptions. Of course you can stil make your app to be subscription based only, without any Newsstand integration, and probably you can manage all subscriptions directly inside your device by saving receipts locally and querying for their validity when needed. The ReceiptCheck class in my application example is done for this. What you cannot to do is to release a Newsstand app without In App Purchase. As one of the most appreciated Newsstand capabilities is to have the device download every new content in the background and at night-time, you must keep a note of each subscription and associate it to a push notification token: you can’t do this without a server, so in such case moving the whole receipt validation mechanism on your server is required.

The source code for this two part tutorial is hosted on GitHub. Note that this is not completely useful if you don’t do the whole setup for push notifications, In App Purchase, shared secrect and so on. My suggestion is: don’t try to run it, don’t use it as production code, but only as reference to better follow this tutorial and get some help if you’re stuck.

Carlo Vigiani

With this article I try to answer some questions.

  •      The company wants to develop its know-how?
  •      What is killing many companies that deal with development?

 

The problems of large IT companies are often sought in the development sector, so that the larger the company and more is looking to outsource their development. In some cases they try to control all the know-how internalising the functional areas at the expense of development.
That said I do not think remotely that there may be a problem in IT due to lack of skills of excellence within the company, rather they are convinced that the development industry is just what brain focuses more interesting, those who devoted to development is almost always a passion for deepening knowledge.
For this reason I see the problem of development focused on how developers are put together in the company, how they are managed and why they are made and what the criteria are entrusted roles.

In the experience I had been able to see the results of international excellence and quality only in brief moments, only determate “happy islands” that the market was ready to absorb. These development groups are evaporated by the time many of the companies I’ve known.

The assumptions behind the recruiting developers.

To explain this situation I’m going to make explicit some of the tacit assumptions that often underlie a large company of recruiting a team of business development. This is a crucial point because, in most organizations, those who influence these decisions in most cases will never be held accountable.

Based on the ideas of Ash Moran, the assumptions of the organization in this question appear to be the following:

  1. Developers are fungible
  2. The productivity is proportional to the duration of development
  3.  The requirements are all necessary

1. Developers are fungible

Tom de Marco, in his ” Slack:Getting Past Burnout, Busywork, and the Myth of Total Efficiency,” tell about “the myth of a fungible resource.”
Many jobs in the factory and warehouse are fully fungible in the sense that the time to bring someone up to full productivity is virtually irrelevant (hours or days). This is not true when it comes to software development, where even if a new hire knows the programming language, given the context, will take a long time to learn the basic code and business methods.

I do not think that developers are fungible (at least in most cases), but I have attended countless meetings in which decision makers were behaving as if this hypothesis is valid. Every time estimates in hand, the vast majority of managers acting as if a new developer can immediately increase the productivity of the team.
This assumption is in contradiction with what the developers think specifically about the nature of their work.

2. The productivity is proportional to the duration of development

There are two degenerative forms of thought to this hypothesis:

1) The idea that a developer who works 10 hours a day will be 25% more productive than one developer to work 8 hours a day

2) The belief that a team of 10 developers is 25% more productive than a team of 8.

I spoke of degeneration as we are convinced, like Ash, that the nature of software development is the creation of new knowledge, a concept that I described in a previous article.
We must think of dvelopers figures as they face a creative task. A job that involves constantly programmer, called increasingly to make logical decisions.

The hypothesis-productive-time is based on the idea that productivity can be represented as a linear scale at right angles. This is not true in the development, for the simple reason that the complexity in managing a team is not necessarily related to the number of people involved, but the nature of involvement and communication is needed to accomplish a given task.
Just think that sometimes is easier to play a role in many people, rather than trying to put 4 people agree on the choice of which movie to go see after dinner.
Obviously depends on the job, as well as some major IT projects you can do better with a small team.

Inattention is the main cause of major bugs.

Let me point out an interesting article: Do You Suffer From Decision Fatigue? ; il cervello umano ha una capacità limitata di fare scelte, e una volta stanchi, ci trova spesso a ricercare scorciatoie.

3. The requirements are all necessary

In most large software companies, functional requirements are defined outside of the development team. Unless the development team is not writing software only for himself, the so-called “Functional Area” (Functionals) will be involved in drafting a document that describes the work to be done by the development industry. Then sometimes it happens that 30% of the functionality in the software will never be used or not needed, then at least 30% of development time becomes pure waste. However, many teams are contractually obliged to provide a specification (document functional) without reference to the value of the specific characteristics of the same, this can be a source of bugs hard to heal.

4. The engaged team

When the development team is not operating at full capacity, it loses at least 25% of the time to rework and perform maintenance. If this happens the team does not produce high quality code, even though the skills of existing team are very high. Some bugs are introduced by developers who are tired and too stressed. The communication overhead reduces productivity in the short term
5. The team size
How many developers you should be taking?

The increased capacity is not the only reason why you should hire people. A very good argument is the redundancy. The teams are very small vulnerable to Murphy’s law, if your sole developer gets hit by a bus, the project will be in grave danger. But it is also possible that a team of 10 people and devastated by a single incident in the same bus. Some questions about the size of various work teams are detailed in an article by Christopher Allen entitled The Dunbar number as a limit to the size of groups.
A small teams may be less risky than it appears, because the developers are very rarely hit by bus, as is true though that must be managed as I very rarely leave their jobs for paymet reasons.
Programmers frequently leave the team due to poor working conditions, conditions that are almost always caused by the decisions of managers.

There is also a situation where you do want to increase the size of your team: when the person you are adding has the knowledge and experience to help improve the effectiveness of all others. In this case, however, their responsibilities must extend well beyond the pure development.

 

6. What to do?

The first thing is to step back and see if you are trying to solve a problem primarily caused by systematic futility in providing a greater effort to the team.
We know that if a Captain of a ship, which saw a flaw, order to all the sailors  to empty the water rather than monitor the situation and call a single engineer to repair the leak, would be ineffective.
Fred Brooks gave Brooks’s Law more than thirty years ago: “Adding manpower to a late software project makes it later.”
Improving the productivity of a team that develops software is difficult. It is about understanding the business, the team, the story and the obstacles that block progress. They are facing a complex problem, context-sensitive.
We see the world filtered through the metaphors that we can express.

 

Il costo di un’ App per iPhone & iPad

This is the italian translation of the article Dear business people, an iOS app actually takes a lot of work!, written by Kent Nguyen. Thanks Kent for giving us permission to publish this translated article.

 

Il grande quesito: quanto costa un’app per iPhone?

Questa è una domanda estremamente comune che viene sempre chiesta da un sacco di persone che lavorano nel mondo degli affari oppure da clienti non molto esperti di tecnologia. Senza dubbio, ogni volta che ho fornito una stima iniziale prima ancora di formalizzare e analizzare in dettaglio le specifiche, ho potuto vedere sui loro volti l’espressione di shock a causa della inaspettatamente alta quotazione.

Inoltre nessuna delle mie quotazioni si è lontanamente avvicinata ai valori discussi in, nel quale vengono discussi i costi di sviluppo dell’app Twitterific. Nonostante il fatto che la domanda originale fosse stata posta nel 2008 e la migliore risposta (da uno degli sviluppatori di Twitterific) fosse arrivata nel 2010, è ancora molto precisa all’inizio del 2012 ed è facile prevedere che lo sarà almeno fino alla fine dell’anno.

Cosí, con il crescere del numero di imprese che desiderano avere un’app per iOS, penso che sia una buona idea spiegare perché i costi siano effettivamente alti cercando di dividere i vari passi e spiegare le variabili coinvolte. Spero che questo articolo sia di beneficio per i non sviluppatori e gli uomini d’affari che devono prendere delle decisioni o semplicemente vogliono comprendere il processo. Le idee in questo articolo ovviamente non sono ristrette al solo mondo iOS ma possono essere estese ad altre piattaforme (Android, Windows Mobile, forse Blackberry).

Checklist: prepararsi ad un’app per iPhone

Il procedimento non è affatto semplice e cerco innanzitutto di informare il cliente a fare tutte le considerazioni guidandolo attraverso questi passi:

PRIMO: Una delle maggiori scoperte che ottengo parlando con i clienti è quanto siano inconsapevoli delle grande infrastruttura necessaria per un’app per iPhone. Dato che essi assumono che un’app sia semplicemente un’app, si aspettano che gli venga fornito il prezzo di fare qualunque cosa con l’app senza tener conto di problematiche quali: avere un server di supporto col quale l’iPhone comunichi, dove immagazzinare i dati dell’utente. La prima volta che incontrai un tale cliente ero furioso ma in seguito ho realizzato il fatto che il concetto di client-server non deve essere dato per scontato tra i non programmatori. Avevo sbagliato, i manager di solito non hanno il senso-tecnico comune che noi programmatori ci attendiamo.

Perciò, cari lettori non tecnici: è necessario che disponiate di un server nel quale memorizzare i dati per qualunque tipo di app che come minimo debba fare qualche autenticazione (login) o qualunque tipo di personalizzazione che volete cambiare in seugito o comunque qualunque operazione che richieda il recepimento di informazioni dall’utente (sto cercando di usare il linguaggio il più semplice possibile).

SECONDO: Dato che avete bisogno di un server, bisogna fare in modo che l’iPhone possa comunicare con tale server, inviando e ricevendo dati. Non esiste una maniera standard, non esiste nessun componente plug-and-play per fare questo, ogni cosa va customizzata. Questo è analogo a creare il vostro linguaggio personalizzato: non volete che gli altri comprendano ciò che state dicendo ma le due estremità, telefono e server, devono capirsi.

Questo processo consiste nella creazione di API (Application Programming Interface) per la vostra app. Queste API devono esistere prima che si proceda con lo sviluppo dell’app. Perché? perché prima di cominciare a comunicare occorre definire il linguaggio! Questo ci porta al prossimo passo, come creare queste API.

TERZO: Non prendere questo passo alla leggera, le API hanno un’importanza pari al 50% dell’intera soluzione. Fare un’API è come mettere in piedi un sito web. Prima devi definire i dati, quindi la logica di business, quali sono i parametri di ingresso a tale logica, come interagiscono fra loro i vari moduli quando accade un evento. Per semplificare, il risultato finale è un sito web completo dove però le pagine non mostrano risultati grafici ma solamente del testo che verrà compreso dalla nostra app: ad esempio una pagina di autenticazione conterrà, in caso di successo, la semplice parola YES.

L’iPhone quindi farà una serie di richieste a questi punti terminali predefiniti (pagina di login) usando il formato di ingresso predefinito dall’API (nome utente + password) e quindi interpreterà il risultato fornito da queste pagine in risposta alla sua richiesta (YES/NO). L’app senza questo non potrà mai registrarsi e fare il login magicamente da sola.

Ci sono *un sacco* di variabili che devono essere prese in considerazione in questa fase, come preparare un server, selezionare il linguaggio di programmazione con cui scrivere le API, dove immagazzinare i dati per minimizzare i tempi di comunicazione, ecc.

QUARTO: Queste API o sono già pronte e ben documentate dal vostro team interno per essere fornite allo sviluppatore iPhone oppure preparatevi a pagare di più che solo per la pura app. In funzione delle conoscenze dello sviluppatore che avrete contattato per farvi l’app, egli/ella potrebbe avere o meno le capacità per fare ciò di cui avete bisogno. Se lo sviluppatore è in grado di fare questo lavoro, allora vi consiglio fortemente di affidargli anche questa parte del progetto dato che egli sa esattamente quali API servono per far funzionare l’app al meglio.

Nel caso abbiate già le API dovrete dare allo sviluppatore la possibilità di parlare apertamente e liberamente con il vostro team di back-end e non limitarvi a dargli la documentazione; questo perché il più delle volte egli richiederà che venga fatto del lavoro in più (più API) per supportare l’applicazione mobile in maniera appropriata.

Adesso, la parte iPhone

Caspita, tutto questo per essere appena pronti a sviluppare l’app e non siamo ancora partiti! In generale, qualunque cosa riguardo iOS è molto restrittiva. Dovete quasi sempre aver definito circa il 100% dello scopo e del design prima che lo sviluppatore possa partire con la programmazione; diversamente dallo sviluppo di siti web, lo sviluppo di un’app per iOS sotto contratto ha pochissimi margini di cambiamento:

Disegnare l’interfaccia: La scelta se si devono utilizzare i componenti grafici standard o personalizzati deve essere presa già dall’inizio, dato che l’architettura dell’intera app dipende da come si vuole l’interfaccia e da come la utilizzeranno gli utenti.Un esempio è la Tab Bar in basso: se si vogliono i bottoncini colorati invece di quelli monocromatici standard, la modifica al codice è sostanziale!

Il codice è fortemente integrato: Con i siti web voi potete aggiungere semplicemente una pagina in più, quindi create un link a quella pagina ove richiesto. Non potete fare questo con un’app per iOS, dato che ogni cosa va decisa all’inizio e ogni cambiamento può risultare in cambiamenti significativi in altre parti dell’app. Il modo in cui il codice iOS è strutturato è come quello di una breadboard (le basette sperimentali per circuiti elettrici), dove ogni cosa è collegata con fili: voi potete sempre cambiare delle cose qui e là ma se tocchi il filo sbagliato allora l’intero circuito smetterà di funzionare. Anche se viene usato del codice estremamente ben strutturato la flessibilità non aumenterà molto. L’aggiunta di un bottone email addizionale nella schermata “About” potrebbe richiedere un ridotto numero di linee di codice addizionali, ma l’aggiunto di un bottone “Facebook Like” sulla stessa pagina è una cosa completamente differente e non ci può attendere che venga fatto in poche ore.

Convertire un’app per iPhone in un’app iPhone/iPad universale: Questa è la peggiore ‘funzionalità aggiuntiva’ presente nei contratti di sviluppo di app per iPhone. Questo perché un’app per iPad non è una banale funzionalità aggiuntiva. Le app per iPad sono di solito molto più complesse delle app per iPhone e il più delle volte sono richiesti un’interfaccia e un meccanismo di interazione completamente differenti. Non solo quello, dato che anche le API potrebbero essere diverse: l’app Denso, che ho sviluppato (e quindi conosco), ha alcune funzionalità esclusive dell’app per iPad che richiedono dati addizionali dal server. Inoltre l’iPhone e l’iPad richiedono esperienze utente differenti.

Dunque siete pronti a partire?

Spero che dopo aver letto questo abbiate un’idea più chiara di quel che è necessario alla vostra ditta per sviluppare un’app per il mondo mobile. A meno che non facciate un’app completamente offline (come una Calcolatrice!) che non raccoglie dati dagli utenti, non potrete pretendere che questa vi venga sviluppata a un prezzo basso. Dopo aver considerato le variabili elencate sopra, se non potrete giustificare lo sviluppo a contratto allora l’altra opzione è assumere a tempo determinato dei progettisti a tempo pieno che lavorino a tempo pieno per l’intera durata del progetto.

D’altro canto, se decidete di andare avanti e affidare in outsourcing il lavoro, c’e’ un’altra cosa da aggiungere: le lungaggini burocratiche. Se lavorate in una grande azienda o in un ambiente molto regolamentato, il vostro lavoro sarà essenzialmente di aiutare lo sviluppatore ad evitare le lungaggini burocratiche che potrebbe incontrare lungo la strada e talvolta avrete necessità di aggirare un pochino le regole. Ho parlato con molti clienti e ho potuto notare il loro scetticismo quando ho cercato di saperne di più sulle loro API, dato che essi o non desideravano esporsi maggiormente per non violare le loro regole di segretezza, e non potevo biasimarli, oppure non possono portare certi dati al di fuori del perimetro aziendale, oppure semplicemente (e questa è la cosa peggiore) le regole di branding aziendale richiedono che ogni singola pagina dell’app presenti il logo dell’azienda (!!!). Alla fine ho preferito non lavorare con questi clienti dato che non potevo immaginare quando a lungo avrei penato per ottenere anche un minimo supporto sulle API di cui avrei avuto bisogno.

P.S. Avrete bisogno di tempo, un sacco, per cui siate pazienti.

 

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close