1. ARC, or why you will love LLVM

    Don’t take me wrong, I strongly believe that anyone writing a compiler deserves my respect. Is not a task for the feeblest. Yet, my relationship with GCC was not always a good one. How not to hate the cryptic messages spilled by the parser from time to time? Well, let’s praise Stallman irreducibility, Apple condemn GCC and replace it with LLVM1. Regardless of the actual reasons, the change brings a better compiler to the table. One that can parse and understand code even better than my cocker spaniel, which is much more of what GCC gives us. And because the compiler is able to understand the code, well, to understand it a little better than GCC, then Apple decided that LLVM can take care of the memory-management tasks. In Apple own words:

    “The compiler has a complete understanding of your objects, and releases each object the instant it is no longer used, so apps run as fast as ever, with predictable, smooth performance.”

    And yes, the best part is that this is not GC. It is just let the compiler insert the release when needed. ARC works on top of the familiar reference counting.

    Enabling ARC

    Basically, ARC requires Apple LLVM compiler 3.0 (or later, as the time of writing, the default compiler is Apple LLVM 3.1), and the compiler flag -fobjc-arc set. Both of these requirements are set by default by Xcode 4.2 and later.

    Ownership

    As you must remember, the only secret of reference counting is to keep an eye on ownership.

    • You are owner of every object you create (using +alloc, +allocWithZone: or +new.
    • You can share ownership of an object (messaging it with -copy, -mutableCopy or -retain)
    • When no longer needed, ownership is relinquished with -release.
    • Only relinquish objects that you own.

    To ease the task, ARC introduced a few qualifiers to instruct the compiler how the objects ownership would be handle.

    __strong

    Default qualifier.

    Semantically,

    NSString __strong * someString = [[NSString alloc] initWithString:@"some string"];
    

    Is the same of

    NSString * someString = [[NSString alloc] initWithString:@"some string"];
    

    The ownership is relinquish at the end of the present scope. This means that the release message is send automatically when the control flow leaves the scope where the strong variable was obtained.

    By the way, any variable qualified with __strong, __weak and __autoreleasing are initialized to nil.

    id __strong someStringVar; 
    id __weak someWeakVar; 
    id __autoreleasing someAutoreleasingVar; 
    

    Is semantically the same of

    id __strong someStringVar = nil; 
    id __weak someWeakVar = nil; 
    id __autoreleasing someAutoreleasingVar = nil;
    

    This seems small, but add o the security of the code (we are no longer dealing with undefined states).

    The strong reference will generate ownership even for objects that are not created.

    NSSet __strong *set = [NSSet set];
    

    Here set is owned for the whole life of the scope.

    Members variables can be qualified as __strong as well. In fact, because the compiler can insert automatically the members variable, all we need to do is to define the property.

    @property (strong) CLLocation *latestKnownLocation;
    

    And obviously, synthesize it.

    @synthesize latestKnownLocation; 
    

    As long as the class instance is alive, there is going to be a strong reference to latestKnownLocation.

    __weak

    So, by default (we don’t even have to type __strong), the compiler will take care of the memory management most of the time. But, what happens, for instance, when two objects refer each other. That’s exactly the kind of relationship that exists between an object and its delegate. We have a tableViewDelegate which is going to serve as a delegate for a UITableView. If the table view delegate property is qualified as strong, and the same happens with the tableView property of the delegate, then, when the delegate reference counter is never going to be zero, because there is always a reference from the table view, and the table view reference counter is also impossible to reduce to zero, because it is referenced from the delegate. This is circular reference.

    To avoid these kind of situations, the rule of thumb is not to claim ownership of delegates and other objects that refers to each other (like IBOutlets for instance). Let’s revisit our previous example, because the table view does not claim ownership of the delegate, the delegate can be deallocated with no problem, and because there is no delegate referencing the table view, the the table view can also be deallocated. Even better, when the object that a variable qualified as __weak is discarded, the variable value is set to nil.

    The __weak qualifier is only available for iOS 5 (or later) and OSX Lion (or later). For older OSs, __unsafe_unretained qualifier must be used instead.

    __unsafe_unretained

    This qualifier exclude the variable from ARC mechanisms. Because no check is perform, and references are not niled, if you set a variable as __unsafe_unretained you hold the responsibility of checking if the object is still there when needed.

    __autoreleasing

    Because ARC handles the little nuances of memory management, it is very rare to use auto release mechanism explicitly, thou the environment provides the needed tools.

    The thing is that when an object is referenced but not created, i.e., none of the methods in the family +alloc, or -copy is called, the object is automatically registered to the auto release pool. When an object is returned from a method, the compiler checks the name of the method. Naming convention is important here because the compiler used the method name to know how to handle the returned object ownership.

    Most programmers are going to use __autoreleasing mainly to handle errors via indirect pointers. In ARC indirect pointers are by default qualified as __autoreleasing. The method that handle the error will take an __autoreleasing parameter:

    - (BOOL)performWithError:(__autoreleasing NSError **)error {
        // try something prone to failure
        if ( failure ) {
            *error = [[NSError alloc] initWithDomain:@"Some Error Domain" 
                                            code:101
                                        userInfo:nil]; 
        return NO; 
    }
    return YES
    }
    

    And the caller portion would be something like

    NSError __autoreleasing *error = nil; 
    
    if ( ![self performWithError:&error] ) {
        // Deal with the error
        NSLog(@"error: %@", error); 
    } 
    

    Legacy Code

    There are plenty of code that is not ARC ready (yet). That’s not a big deal. Once again, ARC is not GC, and it works on a a copyable unit basis. To add non-ARC units to your app, Select the Target you are working with, then the Build Phases tab, and look for legacy units in Compiled Sources. Add -fno-objc-arc to each one. Recompile. You are done.


    1. You would like to think that they choose compiler over the other because one is better, but that’s not the whole history. The tipping point was the more forgiven nature of LLVM License 

  2. Los momentos de mi vida en los que yo he crecido, tienen que ver con los fracasos; los momentos de mi vida en los que yo he empeorado, tienen que ver con el éxito. El éxito es deformante. Relaja, engaña, nos vuelve peores, nos ayuda a enamorarnos excesivamente de nosotros mismos. El fracaso es todo lo contrario: es formativo, nos vuelve más sólidos, nos acerca a las convicciones, nos vuelve coherentes. Si bien competimos para ganar, y yo trabajo siempre para ganar cuando compito, si no distinguiera qué es lo realmente formativo y qué es secundario, me estaría equivocando mucho.

    — Marcelo Bielsa

  3. jtotheizzoe:

    Happy 94th Birthday, Richard Feynman!

    Bonus: Here is a video of Dr. Feynman, playing bongos, and really wanting some orange juice.

  4. Product Definition

    Time after time good ideas are wasted in poorly designed apps. The problem, usually, is the lack of understanding of the target of the app, and how the app is going to be used in the real world. The world of the app has to be chartered before the first line of code. We have to figure out what we are going to deliver to our customers in advance. We have to be intentional. No real world architect dare to start building without a blueprint, and best architects spend lots of times with their customers in order to know what they want, even before the blueprint.

    List of ‘Nice to Have’ features

    Most of the time, every single app starts with a ‘great idea’, and a big list of ‘nice to have’ features. The problem is that compiling a list of features is easy, and is also easy to implement them. Not trivial, but easy. The end result? Apps that are no longer solutions but containers where we shoehorn features. The true genius, we already know that, is not to add, but to remove what is not really needed. Ask Leonard Cohen if you don’t believe me.

    That big list is not what we need. Our goal is to define a solution. The very best apps on the App Store are those that solve a problem for a customer. The problem doesn’t have to be huge, but the solution has to be useful.

    Defining a solution

    One of the best way to make sure we are accurately defining a solution instead of just creating a container is to distill the most important aspects of the app in one sentence. We first need to define what makes out app different from the rest of gazillion apps in the store. What makes it special for the customer. And yes, it has to be something special, otherwise, why bother? Then we have to think about the best solution for the need, and finally, the audience. The audience definition, the target in marketing parlance, is critical here. It will help us to better understand the problem at hand, and obviously, improve the solution. Feel free to use the next template:

    (app differentiator)(proposed solution), for (app audience)

    Let’s try to exercise a little this idea. Let’s pretend we realize there is no good enough medical imaging apps in the store. Sure, there are plenty of excellent of excellent imaging apps out there, but they all lack tools to help doctors measure anatomical features. Our proposed solution, then, is to create an app that contains these measurement tools.

    So, we already know the audience of the app is going to be composed by doctors. That’s not enough. Remember, the better we know our target, the best solution we can deliver. For instance, the prototypical customer of the app is going to use it in his or her office? When on the go? Or perhaps when performing a surgery? Three different scenarios that ask for three different solutions. And we might be talking about the same person, just changing the context. When in her office, the doctor has plenty of time to focus on details. We can add more items to the toolset, and let the doctor experience drive the flow. The UI might be monochromatic, clean, scalable and productivity oriented. When on the go, the doctor has no time to read the image and he can use the help of some Artificial Intelligence to focus on features that are particularly interesting. The toolset might be limited, but connectivity tools should be add to let the doctor report back to the hospital, if needed. When in the OR, the doctor does not need a lot of tools, and certainly she is not going to email anything. Buttons should be big, easy to tap, and colors should be shocking. Knowing a little bit more about the target pays, a lot.

    With that in hand we can think on:

    Easy to use Medical Imaging app to review and report for doctors on the go.

    or

    Comprehensive Medical Imaging app to analyze, edit, organize and share for doctors at the office.

    or

    *Really easy to use Medical Imaging tool to help visualize key anatomical features for doctors at the OR. *

    The product definition statement then is going to be the cornerstone of the whole design process. Now you can start compiling the list of desired features, you have a tool that will help you to decided if the feature at hand worth the list. You can ask yourself if the new feature is critical or not to fulfill the product definition.

    The relevance of each feature is really important. The smaller the feature set, the better. That’s not equals a cripple app. It make no sense to deliver with fewer features than the needed to accomplish the goal of the app. If the product definition ask for 50 features, then go for it.

    The rule of thumb is to include the most frequently used features by the majority of the users. Because the app is simple, doesn’t mean it won’t be valuable to your customers.

    Road maps

    But not features are critical. The ones that are, obviously, should be there since day one, but perhaps there are others that can be added later. A road map is a helpful tool to know what has to be there in each version. Version 1.0 is for the most critical features. If you are not embarrassed by version 1.0 feature set, then you waited too long. You have to build a road map, you have to know that feature x, as important as it is, might not be critical, if that’s the case, feature x is going to be introduced in version 1.1 or 2.0. Software development, specially nowadays, is not a hit or loose. At least not regarding the feature set (quality is a different issue, is hard to convince a user to give another try to a crappy app). We are not burning disk anymore to deploy software. Users are going to be happy if they discover a new version of the tiny app that does one thing, but does it really well, specially if this new version add more features. And the App Store is your friend here, it is going to pop your new version as soon as it is available to all the users. Software distribution is cheap, version 1.1 could be deployed a week later than 1.0. No problem.

    Road Maps are key. You have to be able to allocate resources for the whole map. Version 1.0 is just one step, perhaps the most important (if it is crappy, then you have no second try). Please, read the article of Matt Mullenweg I’m linking above. The first version of the iPod was quite limited, but the people behind it was really careful when choosing the critical features that were needed to implement, and the implementation itself. The second generation packed more features, and the people love them.

    But why wait till the whole feature set is complete. Because then you can be pretty sure your market is lost. And also because you are going to learn a lot from real users in the real world.

    Flexibility

    That being said, it is really, really important to remember that nothing is carved in stone. You have to be flexible, and hear what the audience is asking. Real world can be cruel, but if we are not working for our audience, then it doesn’t matter what we are doing. The application definition statement might be perfect, the feature set might be comprehensive, the road map might be smart. But as soon as version 1.0 hit the store a user will point the elephant in the room, and you might need to rethink the whole feature set and road map. That’s the beauty of this industry, is pretty much alive.

    And because you need to be flexible, you have to learn the design patterns that will help you. We have talked about patterns in the past, and I promise I will be back to them. The important thing is to try to devise an architecture where the different modules are not tightly coupled, and you can easily change how they interact. For instance the delegate pattern is better than subclassing (or retain the responsibility of a task in a single class).

  5. Patching git

    Perhaps one of the less known, and yet more useful commands in the git interactive add is patch. Let’s say you start working on a file to fix a bug (yes, I know, your code does not have bugs, but let’s pretend for a moment), Once in the file, you found a line that needs some refactoring, and just because you are a really nice person, you add some comment to a method that has nothing to do with the line you’ve refactored, or the bug you fixed. Three different things in the same file. Sounds familiar? Sure you can issue something like:

    git commit -a -m "Cleaning Code"
    

    And you are not lying. But, for the sake of being a good citizen, wouldn’t be better to split the whole stuff in three discreet commits, one for the line you’ve refactored, one for the bug you’ve fixed, and one for the comment you’ve added? This is exactly what path can do.

    Instead of adding everything in just one stage, let’s enter the interactive session:

    $ git add -i
               staged     unstaged path
      1:    unchanged      +14/-14 algorithms.py
    
    *** Commands ***
      1: status   2: update   3: revert   4: add untracked
      5: patch    6: diff     7: quit     8: help
    What now> p
    

    Type p in the prompt, and git will list all files in the working directory:

             staged     unstaged path
    1:    unchanged      +16/-15 algorithms.py
    Patch update>> 1
    

    Then you just need to select the number of the file (or files, because you can add many files at one if you need) you want to path. In this case 1. Git is going to print out a lot of things once you’ve done selecting files. It might be a little overwhelming, so let’s take a look at it.

    First, GIT will tell us what is taken into account, In this case the version a and the version b of the content of the file algorithms.py:

    diff --git a/algorithms.py b/algorithms.py
    index 5a835ea..f9d0cdb 100644
    

    Then, it says that the content from file a (the HEAD), is identified with - and the content from b is identified with +

    --- a/algorithms.py
    +++ b/algorithms.py
    

    And then the content of the file itself.

    @@ -10,24 +10,25 @@ Copyright (c) 2012 __MyCompanyName__. All rights reserved.
     import sys
     import os
    -from random import randrange
    -
    +from collections import defaultdict
    
     def main():
    -    seq = [randrange(10**10) for i in range(100)]
    -    seq.sort()
    -    dd = float('inf')
    -    xx = 0
    -    yy = 0
    -    for x in seq:
    -        for y in seq: 
    -            if x == y: 
    -                continue
    -            d = abs(x-y)
    -            if d < dd: 
    -                xx, yy, dd = x, y, d
    -    print '%d %d' % (xx, yy)
    +    pass
    
    +def max_perm(M, A=None):
    +    """docstring for max_perm"""
    +    if A is None:
    +        A = set(range(len(M)))
    +    if len(A) == 1:
    +        return A
    +    B = set(M[i] for i in A)
    +    C = A - B
    +    if C:
    +        A.remove(C.pop())
    +        return max_perm(M,A)
    +    return A
    
     if __name__ == '__main__':
    -   main()
    +    main()
    
    +    
    \ No newline at end of file
    

    And finally, git ask what we want to do.

    Stage this hunk [y,n,q,a,d,/,s,e,?]? 
    

    I know, I know, a bit intimidating the list of letters. And Linus seems to know that because, the default value is no other than ? which is going to print a help message:

    y - stage this hunk
    n - do not stage this hunk
    q - quit; do not stage this hunk nor any of the remaining ones
    a - stage this hunk and all later hunks in the file
    d - do not stage this hunk nor any of the later hunks in the file
    g - select a hunk to go to
    / - search for a hunk matching the given regex
    j - leave this hunk undecided, see next undecided hunk
    J - leave this hunk undecided, see next hunk
    k - leave this hunk undecided, see previous undecided hunk
    K - leave this hunk undecided, see previous hunk
    s - split the current hunk into smaller hunks
    e - manually edit the current hunk
    ? - print help
    

    The option we are looking for is s.

    Stage this hunk [y,n,q,a,d,/,s,e,?]? s
    Split into 5 hunks.
    @@ -10,6 +10,6 @@
     import sys
     import os
     from random import randrange
    -
    +from collections import defaultdict
    
     def main():
    Stage this hunk [y,n,q,a,d,/,j,J,g,e,?]? 
    

    Then we can simply choose the hunks that we want to add for each commit. Once we are done selecting the hunk, we can update the content:

        *** Commands ***
        1: status     2: update   3: revert   4: add untracked
        5: patch      6: diff     7: quit     8: help
    What now> u
           staged     unstaged path
    1:        +1/-1      +15/-14 algorithms.py
    Update>> 1
    

    And commit with an appropriate message:

    git commit -m "Importing defaultdict from collections"
    

    If you don’t want to mess with the interactive session (truth be told, I rather not), then thee is also a shortcut to get right into patching mode.

       git add -p
    

  6. Authorization Code flow in depth

    Authorization Code flow in deep

    Perhaps, one of the most secure flows in the OAuth specs, because the access token is never exposed. The authorization is accomplished using an authorization code that then is traded for the actual access token in a server-to-server exchange. The client has no access to the access token. The flow starts when the resource owner is redirected to the API provider. In iOS we can simply start the process inside a UIWebView asking for the appropriate API endpoint, and passing the needed parameters

    Parameter name Required Description
    response_type Yes A token describing what kind of response we are looking for. code if we are asking for an authorization code
    client_id No string or number issued by the API provider
    redirect_uri No URI where the resource owner is going to be redirected after authentication and authorization
    scope No A list specifying the resources we are asking to access. Most API providers use space-delimited lists, Facebook use comma separated strings
    state No, but recommended String with a unique value to validate the callback. Usually a hash

    To these parameters list, API providers can add their own values, for instance, in Foursquare you can specify if the device is touch based with display=touch.

    Here the authorization call performed with Cocoa:

    NSString *urlString = [[NSString alloc] initWithFormat:@"https://foursquare.com/oauth2/authenticate?display=touch&client_id=%@&response_type=code&redirect_uri=%@", kFourSquareOauthKey, kFourSquareRedirectURL];       
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]]; 
    [urlString release]; 
    [self.webView loadRequest:request]; 
    [self.webView setDelegate:self]; 
    [self.view addSubview:self.webView];  
    

    If the authorization is granted, the resource owner is then redirected to the redirect_uri with the following parameters added by the authorization server.

    Parameter name Required Description
    code Yes This is the code generated by the server to be traded by the access token. Should not be used more than once. If used more than once, the server must deny the request and should revoke all tokens issued based on that authorization token
    client_id Yes when present in the request The value send by the client. Should be used to validate the callback and prevent CSRF attacks.

    On the other hand, if the authorization is not granted, then the user is also redirected to the redirect_uri but this time with a parameter named error with a code identifying what wen wrong. The API provider can also add an error_description with a human readable string explaining the problem, and an error_uri with the location of a Web resource with more information about the problem.

    The allowed codes for the error parameter are:

    Error Code Description
    invalid_request The request is missing some required parameter or is otherwise malformed
    unauthorized_client The client is not authorized to use this method to request an authorization
    access_denied Either the resource owner or the authorization server have denied the request
    unsupported_response_type The request is not supported by the authorization server
    invalid_scope The requested scope is invalid, unknown, or malformed
    server_error The authorization server was unable to process the request
    temporarily_unavailable The* authorization server* is currently unable to handle the request due to a temporary overloading or maintenance of the server

    Exchange authorization code for an access token

    Once the client gets the authorization code, it can be traded for an access token performing a HTTP POST request composed with:

    Parameter name Required Description
    grant_type Yes What type of gran access is required? authorization_code for a new authorization access code, refresh_token to renew the token, password when we have the resource owner password to trade for the access token, client_credentials when we have resource owner login credentials
    code Yes The code obtained in step 1
    redirect_uri Yes if the value was included in the authorization request If redirect_uri was included in the authorization request, should be also included in this call. The UIR must be the same
    refresh_token Yes to renew the token The refresh_token produced by this endpoint the first time it is called

    The client_id and the client_secret also has to be included in this call. They can be send as a HTTP Basic Authorization header (with client_id as the login, and the client_secret as the password). Some API providers allow users to send the two tokens as simple parameters for the request as well.

    If the access token request is valid, and authorized, the authorization server issues an access token and sometimes a refresh_token as a JSON formatted payload:

    HTTP/1.1 200 OK
    Content-Type: application/json;charset=UTF-8
    Cache-Control: no-store
    Pragma: no-cache
    
    {
       "access_token":"2YotnFZFEjr1zCsicMWpAA",
       "token_type":"example",
       "expires_in":3600,
       "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
       "example_parameter":"example_value"
    }
    

    The access token and, if available, the refresh token should be kept secret. Many providers issue a short-lived access token. If that’s the case, you will find expires_in and refresh_token as parameters in the JSON response. The expires_in parameter indicates the remaining lifetime of the access_token in seconds. When the access token expires, the refresh token can be used to obtain a new one. To refresh the access token we need to perform a HTTP request to the token endpoint, specifying refresh_token for the grant_type parameter, and adding the refresh_token.

    The access token is then used in all the API calls, without the need to crypto sign them anymore. Sometimes, we can add the token as a simple parameter in the request, thou, most of the API providers, prefer the token to be dispatched as a HTTP header.

  7. OAuth Authorization flows

    OAuth defines four different grant types to obtain authorization:

    • Authorization code: After the resource owner has authorised access to the data, he or she is redirected back to the client application with an authorization code as a parameter in the callback url. This code is then traded for the actual access token. The process is performed server-to-server and requires the client_id and the client_secret.
    • Implicit grant for browser based client-side applications: Once the resource owner gives authorization, an authorization token is produced and send to the client using a hash fragment. Here there is intermediary authorization code.
    • Resource owner password-based grant: if the client is highly trusted (for instance, was created by the owner of the resource server), the resource owner login credentials can be traded by a OAuth access token. The user password is exposed, but should not need to be stored on the device. After the initial authentication, only the OAuth token should be stored.
    • Client credentials: here the client is not acting as a middleman between the resource owner and the resource server, but on behalf of itself, and thus, only need its own credentials.

    Note included in the core specification, but also very popular, we can add two more flows:

    • Device profile: when the capabilities of the device are not strong enough, the process can be started with it, and then a code is shown, and the resource owner is asked to use a web browser to grant access to the device typing a code.
    • SAML assertions: big companies are not famous for their flexibility. If they have already a SAML authorization server running, SAML 2.0 assertions can be exchanged for OAuth access tokens.

  8. OAuth 2.0 Debate

    It is there all the time, one of the most important task for engineers is to strike a balance between security and usability. You can build a pedestrian bridge performing a load rating for big trucks, but is going to be expensive, and harder to build. The same is also true in software engineering. There are zillions of reasons to prefer OAuth over other protocols, but some engineers found it hard to implement. They claim that OAuth 1.0 requirement to sign all API calls was challenging (to put it mildly). Because of that, and try to ease the learning curve, and thus increase the OAuth adoption rate, OAuth WRAP (OAuth Web Resource Authorization Profiles) was introduced as a predecessor to OAuth 2.0. Given the greater prevalence of SSL/TLS, OAuth WRAP eliminate the signing requirement introducing bearer tokens. Some people is not thrill about the tradeoff, but then we have a new standard.

    ###Certificates The major concern about bearer tokens is that users (and here users are developers of packages that consumes from sources guarded with OAuth 2.0) will fail to verify the SSL/TLS certificate chains. This is not a weak spot of the protocol itself, which, in fact, specify the correct use of certificates. The moral of this tale is certificates should be checked, always.

    • Certificates chains should ends in a valid and trusted Certificate Authority (CA).
    • The hostname included in the certificate returned by the server should be the same we have asked.

  9. OAuth

    OAuth has a bad reputation. many claims that it is hard to implement, and some are really confused by the flow. And is a shame, because OAuth is a wonderful protocol to ensure how we want to share information. This is the first of a hopefully not so long series of post to explain how to use OAuth.

    First, we are going to take a look at the basic terminology.

    • Authentication: This is the process used to identified a user, in other words, making sure the user is who he or she claims to be. Typically, this involves the checking of some tokens, like the username, or email address and a password. The authentication process can be handle by the app that wants to id the user, or can be delegated to a third party identity management in what is called a Federated Authentication.
    • Authorization: Despise the fact that many use authentication and authorization as interchangeable concepts, the authorization process is the one that, once the user has been identified, checks the granted permissions. For instance, an administrator might have read / write access to files that a simple user can only read, or perhaps has no access at all. With OAuth, an actor can delegate his or her own authorization status to a third party to perform actions on their behalf.
    • Resource Server: This is the server that host the resources that are protected with OAuth. Typically, this server implements a series of APIs to let consumer access the content.
    • Resource Owner: The account owner
    • Client: The API consumer application. Clients are defined as:
      • Server Side Client: This kind of clients run as a Web application, and consumes the API calls in the back. The resource owner has no access to the OAuth client secret or any other access tokens.
      • Client Side Application: They run on a web browser, where the client has access to the application code, or can perform calls to the API. The credentials are not trusted to be kept confidential (the code has been delivered to a third party), and some API providers might not issue client secrets for applications running like this.
      • Native Application: Very similar to client side applications, except they are not run by a web browser.
    • Authorization Server: Middleman piece in the stack that ask (and hopefully gets) the consent from the resource owner to gain access to protected resources in the resource server. Once the authorization is granted, it also issues tokens to the client.
    • Bearer Tokens: Most OAuth 2.0 providers relies on bearer tokens to perform authorized requests. The simple possession of a token grant access to walled resources. Once the client has the token, for most application, nothing else is required (OAuth 2.0 also specify the use of MAC Access Authentication, but is not the most popular implementation). The preferred way to dispatch the token along with API calls is to use HTTP header, because the header is rarely logged or cached.

  10. Wolfram is one of my personal heroes. He is brilliant.

    poptech:

    Steven Wolfram: The Personal Analytics of My Life

    One day I’m sure everyone will routinely collect all sorts of data about themselves. But because I’ve been interested in data for a very long time, I started doing this long ago. I actually assumed lots of other people were doing it too, but apparently they were not. And so now I have what is probably one of the world’s largest collections of personal data.

    Every day—in an effort at “self awareness”—I have automated systems send me a few emails about the day before. But even though I’ve been accumulating data for years—and always meant to analyze it—I’ve never actually gotten around to doing it. But with Mathematica and the automated data analysis capabilities we just released in Wolfram|Alpha Pro, I thought now would be a good time to finally try taking a look—and to use myself as an experimental subject for studying what one might call “personal analytics”.

    You’re going to want to click through and read all of this.