Google admits breaking App Store rules

Google acknowledged breaking the official rules of Apple’s iPhone software development kit when it created the latest version of the Google Mobile application for the iPhone, but denied a more serious charge.

A Google spokesman confirmed Tuesday that Google Mobile uses undocumented APIs (application programming interfaces) in order to use the iPhone’s proximity sensor to prompt a verbal search. iPhone developers were only supposed to use the APIs that Apple published in its SDK when they create their applications under the terms of that agreement.

Google has denied, however, a more serious charge that it was linking to private or dynamic frameworks in the Google Mobile application. That’s considered a big no-no in the development community.

The problem with using undocumented APIs is that your application code could break in the future as Apple updates its software, but a lot of developers appear to have taken that risk in order to deliver a cool feature, such as Google’s verbal search prompt.

Under the original terms of the SDK, however, applications using such techniques were not supposed to make it through to the App Store. As a result, other developers who played strictly by the SDK rules would not have felt it possible to create an application that duplicated Google’s voice prompt using the proximity sensor, whereas those who had the resources to quickly rewrite anything that ran afoul of the App Store gatekeepers could push ahead and test Apple’s limits.

Given Apple’s uneven process for approving applications onto the App Store, the question has continued to come up as to whether Apple’s ability to keep up with the flood of applications into the App Store has been stretched to the breaking point. It’s not clear whether Apple knew Google was using the undocumented APIs when it approved Google Mobile, or whether it simply missed that code.

Google might be forced to rewrite the code for Google Mobile or change the way the application uses the proximity sensor if Apple decides to enforce the terms of the SDK. A number of Apple representatives appeared to be on vacation this week, and so requests for comment are not likely to be immediately returned.

10 important facts to look for in a domain registrar

Every web site needs a domain name and it becomes identity of your organization. Domain registration business is growing fast with Godaddy on the top of the list. But sometimes you may run into serious problems or get surprised in the offering and end result. Technology professionals need a good, dependable registrar that offers the tools, services, and features required to properly research and resolve these issues. There may be various issues like complex DNS issues, dreaded SMTP errors, or confusing IP address troubles etc. which may give you nightmares. Following is a list of 10 important facts which everyone should look for in a domain registrar before purchasing

1: Validity

Always check if your domain registrar is an ICANN accredited, if not move to other registrar regardless of the prices or their offerings. An ICANN-accredited registrar can help and ensure that your organization receives professional, stable, reliable service from a reputable provider.

2: Knowledgeable technical support

There are times when you need support for transferring domains, delegating administrative permissions, or just renewing existing services. You should know that the customer support is supportive enough and capable enough (technically) to help you out. Almost all operate toll-free telephone numbers. That’s to be expected. You may review a domain registrar’s support policies. Some offer live technical chat as well as live telephone support.

3: Intelligent DNS configuration utilities

The frustration that comes with trying to make sense of unintuitive and/or confusing DNS configuration tools can quickly prove overwhelming, particularly when e-mail service or Web site access is down. Even if you have to test a domain registrar’s DNS tools using a practice domain you create only for testing purposes, getting familiar with a registrar’s DNS configuration tools and their usage before administering a live site or production e-mail can prove invaluable. Avoid selecting a registrar whose DNS tools prove difficult to access or understand or that are error-ridden.

4: Delegation tools

Often, organizations prefer to implement a separation of powers when managing domains. For example, senior staff might be the only ones able to transfer a domain, whereas network administrators might need permissions to occasionally update DNS records.

In such cases, delegation authority is required, in which specific permissions can be delegated to respective authorized users. If your organization is likely to find itself in such need, be sure to confirm the domain registrar selected supports such division of responsibilities.

5: SSL Certificates

You might have seen that for all the four services you recieve four different bills i.e.(domain registration, e-mail hosting, Web hosting, and SSL certificate) this becomes confusing, inefficient and costly. Choose a domain registrar that can collect all these services within a single pricing package. Doing so simplifies recordkeeping and administration and lowers costs.

6: Web hosting

Increasingly, many organizations are choosing not to invite port 80 public Internet traffic inside their corporate servers. File servers dedicated to user authentication and file and print sharing, while usually capable of hosting Web sites, are often configured specifically not to allow public Web traffic. Foregoing Web site hosting on an organization’s own local server helps secure the box and protect it from countless exploits.

However, most organizations require a Web presence. Just as with e-mail hosting, companies should look for a domain registrar that also offers competitive Web hosting services. For reasonable fees, organizations can keep such Web-related traffic off their main production servers by taking advantage of registrar Web-hosting packages instead.

7: E-mail hosting

Small organizations don’t want the hassle of managing and maitaining their own servers not they are willing to manage Exchange or SendMail. It’s comfortably easier that domain registrar should maintain e-mail services. Thus, organizations that don’t want to maintain e-mail server administration should look for a domain registrar that can wrap those services within a single, integrated package.

8: Site-building tools

If you aren’t a big organization then you may not need expensive web design firms to develop and maintain your small web site. In order to launch professional, informational Web sites that improve communications with clients and suppliers you can use registrar-provided tools to quickly launch a simple but professional-looking Web site.

9: Easily navigable Web site

Look for a domain registrar whose Web site is well organized. Look for registrars that have carefully designed their Web sites to group relevant tools by topic. Browse a potential registrar’s site to confirm it is easily navigable. Just because a domain registrar has purchased full-page advertisements in an electronics or tech magazine doesn’t mean its services or domain management tools are intuitive or readily accessible.

10: Competitive pricing

This is a very good time to consumer as the competition between domain registrars is fierce. Be sure to review a domain provider’s pricing policies before committing. Pay special attention to potentially hidden fees, such as for domain forwarding or e-mail services. While price shouldn’t be the chief priority, it’s become a buyer’s market, certainly.

Leave me a comment and let me hear your opinion. If you’ve got any thoughts, comments or suggestions for things we could add, leave a comment! Also please Subscribe to our RSS for latest tips, tricks and examples on cutting edge stuff.

Deeper look into Friendfeed API

FriendFeed is the new hotness and many people have asked for an API to take the service to the next level. There aren’t any example apps built yet, nor has there been much developer feedback yet. A whole lot of things just became possible, though.

As for technical details: FriendFeed is first releasing Python and PHP libraries, there’s an undisclosed access limit and oAuth authentication is "coming soon" (we hope so).

If you’re less than on fire about APIs and their potential – check out our post called APIs and Developer Platforms, A Discussion of the Pros and Cons – and know that 16 of the 18 authorities quoted in that post were interviewed entirely through a 3rd party Twitter client using that API.

If you’re a Twitter user you know how essential to Twitter that company’s API has become, an estimated 80% or more of Twitter use comes in through the API and the constellation of 3rd party services that leverage it. The FriendFeed API may be the most eagerly awaited since Twitter’s

This Aint Just RSS Readin’

Casual users should take note that FriendFeed is far more than just an RSS aggregator. Check out the podcast and transcript of our interview with the company’s founders in early February for details. See also my recent interview with RSS keystone Dave Winer, where we discussed FriendFeed more than anything else. You’d have seen it already if you were my friend on FriendFeed.

Commenting, feed and item display, liked-by-a-friend item exposure and a smooth friend recommendation path are some of the key differentiators of FriendFeed. In February at least, only 70% of the feeds coming into FF were RSS feeds, too. The rest are from other kinds of 3rd party APIs that the FriendFeed team has tied into by hand. There are many different Lifestreaming apps, but FriendFeed has a lot of momentum, a good user experience, renders well on mobile and has caught peoples’ imaginations. It’s also got some heavyweight backers.
The Possibilities

Some of the examples from the FriendFeed announcement are these:
"[The API is] designed to make it possible for anyone to payday loans improve FriendFeed or integrate FriendFeed into other applications. You can develop a FriendFeed interface for a mobile phone, build a FriendFeed widget for your blog, or develop an application that makes it easy to post photos to your feed from your iPhone."

I’m cheering for an Adobe AIR desktop interface, APML import/export and some sophisticated item-level recommendations. How about a FriendFeed/Imeem mashup? I’d love to listen to a streaming radio station of all the music that my FriendFeed friends favorite on their respective music networks. Oh the possibilities are many. This is a very exciting announcement.

Requests and Data Formats

All requests to the FriendFeed API are simple HTTP GET and POST requests. For example, you can fetch the JSON version of the most recent 30 public entries published to FriendFeed by fetching http://friendfeed.com/api/feed/public.

All of the API requests that output feeds are available in four formats: JSON, a simple form of XML, RSS 2.0, and Atom 1.0. JSON is the default output format. To request a different output format, simply add an format= argument to the URL:

    * http://friendfeed.com/api/feed/public?format=json
    * http://friendfeed.com/api/feed/public?format=xml
    * http://friendfeed.com/api/feed/public?format=rss
    * http://friendfeed.com/api/feed/public?format=atom

The other API requests, like posting a new comment on an entry, only support the JSON and XML output formats since they do not output feed-oriented data.

Authentication

If you are publishing data to FriendFeed or if you are requesting the feed that includes data from a user with a private feed, your HTTP requests must be authenticated.

All FriendFeed users have a Remote Key to provide third party applications access to their FriendFeed. A FriendFeed Remote Key is just like a password, except that it is only used for third party applications, so it only provides access to the functionality defined by the API. Users can easily reset it if a third party application abuses the API.

All requests that require authentication use HTTP Basic Authentication. The username should be the user’s nickname, and the password should be the user’s Remote Key. You can direct user’s to http://friendfeed.com/remotekey to get their remote key if they have not memorized it. See the FriendFeed API Application Guidelines for a complete set of recommendations of how to present authentication in your application.

The Python and PHP libraries available at http://code.google.com/p/friendfeed-api/ implement authentication for all methods that require it.

Remote Key

A remote key is a kind of password that you can give to third-party applications and websites to let them interact with FriendFeed on your behalf. There are limits to what can be done using a remote key, which means it’s a lot safer than giving a site your FriendFeed password.

JSON Callbacks

The JSON output format supports an additional argument callback= that wraps the JSON output in a function call to a function of your choice. This functionality is available to enable you to use the API with JavaScript within a web browser. For example, http://friendfeed.com/api/feed/public?callback=foo outputs:

foo({"entries":[…]})

Using JSON and callbacks, you can place the FriendFeed API request inside a <script> tag, and operate on the results with a function elsewhere in the JavaScript code on the page.

All authentication is ignored if the callback= argument is given, so JSON callbacks only work with public feeds.

Reading FriendFeed Feeds
Overview
Feed Formats

The JSON form of the feeds has the following structure:

    * entries[]
          o id – the FriendFeed entry UUID, used to add comments/likes to the entry
          o title
          o link
          o published
          o updated
          o user{} – the user who shared this entry
                + id – the user’s FriendFeed UUID
                + nickname – the user’s FriendFeed nickname, used in FriendFeed URLs
                + profileUrl – the user’s profile URL on FriendFeed
          o service{} – the service from which the entry came
                + id – the service’s FriendFeed ID, e.g., "picasa"
                + name – the service’s official name, e.g., "Picasa Web Albums"
                + profileUrl – the user’s profile URL on this service
          o comments[]
                + date
                + user{} – same structure as the user{} structure above
                + body – the textual body of the comment
          o likes[]
                + date
                + user{} – same structure as the user{} structure above
          o media[] – the videos/images associated with the entry
                + title? – the title of the media file
                + player? – the player for this media file (e.g., the YouTube.com URL with the embedded video)
                + thumbnails[] – the thumbnails for this media file
                      # url
                      # width
                      # height
                + content[] – the different versions of the media file
                      # url
                      # type – the MIME type of the media file
                      # width
                      # height

The simple XML format (output=xml) has the same structure as the JSON. The RSS and Atom formats use the standard RSS and Atom attributes for title, link, published, and updated, and include extension elements for all of the other meta-data.

Dates in JSON and dates in the FriendFeed extension elements in the Atom and RSS feeds are in RFC 3339 format in UTC. You can parse them with the strptime string "%Y-%m-%dT%H:%M:%SZ".

Filtering & Paging

All of the feed methods below support the following additional arguments:

    * service – only return entries from the service with the given ID, e.g., service=twitter
    * start – return entries starting with the given index, e.g., start=30
    * num – return num entries starting from start, e.g., num=10

Methods

/api/feed/public – Fetch all Public Entries

Returns the most recent public entries on FriendFeed:

http://friendfeed.com/api/feed/public

Using the FriendFeed Python library:

service = friendfeed.FriendFeed()
feed = service.fetch_public_feed()
for entry in feed["entries"]:
    print entry["title"]

/api/feed/user/NICKNAME – Fetch Entries from a User

Returns the most recent entries from the user with the given nickname:

http://friendfeed.com/api/feed/user/bret

If the user has a private feed, authentication is required.

Using the FriendFeed Python library:

service = friendfeed.FriendFeed()
feed = service.fetch_user_feed("bret")
for entry in feed["entries"]:
    print entry["title"]

/api/feed/user/NICKNAME/comments – Fetch Entries a User Has Commented On

Returns the most recent entries the user has commented on, ordered by the date of that user’s comments:

http://friendfeed.com/api/feed/user/bret/comments

If the user has a private feed, authentication is required.
/api/feed/user/NICKNAME/likes – Fetch Entries a User Has "Liked"

Returns the most recent entries the user has "liked," ordered by the date of that user’s "likes":

http://friendfeed.com/api/feed/user/bret/likes

If the user has a private feed, authentication is required.
/api/feed/user/NICKNAME/discussion – Fetch Entries a User Has Commented On or "Liked"

Returns the most recent entries the user has commented on or "liked":

http://friendfeed.com/api/feed/user/bret/discussion

If the user has a private feed, authentication is required.
/api/feed/user – Fetch Entries from Multiple Users

Returns the most recent entries from a list of users, specified by nickname:

http://friendfeed.com/api/feed/user?nickname=bret,paul,jim

If more than one nickname is specified, the feed most recent entries from all of the given users. If any one of the users has a private feed, authentication is required.

Using the FriendFeed Python library:

service = friendfeed.FriendFeed()
feed = service.fetch_multi_user_feed(["bret", "jim", "paul"])
for entry in feed["entries"]:
    print entry["title"]

/api/feed/home – Fetch the Friends Feed

Returns the entries the authenticated user would see on their FriendFeed homepage – all of their subscriptions and friend-of-a-friend entries:

http://friendfeed.com/api/feed/home

Authentication is always required.

Using the FriendFeed Python library:

service = friendfeed.FriendFeed(nickname, remote_key)
feed = service.fetch_home_feed()
for entry in feed["entries"]:
    print entry["title"]

/api/feed/search – Search

Executes a search over the entries in FriendFeed. If the request is authenticated, the default scope is over all of the entries in the authenticated user’s Friends Feed. If the request is not authenticated, the default scope is over all public entries.

http://friendfeed.com/api/feed/search?q=friendfeed

The query syntax is the same syntax as http://friendfeed.com/search/advanced. The query operators are:

    * who: -restricts the search to a specific user, e.g., who:bret
    * service: restricts the search to a specific service ID, e.g., service:twitter

Using the FriendFeed Python library:

service = friendfeed.FriendFeed()
feed = service.search("who:bret friendfeed")
for entry in feed["entries"]:
    print entry["title"]

Publishing To FriendFeed

All of the calls to publish information to FriendFeed are HTTP requests. You can perform test calls from a web browser using the HTTP Basic Authentication built into your browser at http://friendfeed.com/static/html/apitest.html.

Requests to FriendFeed are rate limited, which, e.g., limits the number and size of thumbnails you can upload in a day. Normal uses should fall well within our rate limits. If you encounter HTTP 403 errors because of rate limits, and you think the limit is erroneous, please let us know in the developer forum.

Create New Entries
/api/share – Publish Links or Messages

A POST request to /api/share will publish a new entry on the authenticated user’s feed. The arguments are:

    * title – required – The text of the new entry.
    * link – The URL of the new entry. If it is not specified, the new entry will look like a quoted message. If specified, it will look like a link.
    * comment – If specified, the given text is posted as a comment under the new entry.
    * imageN_url, imageN_link – The thumbnail images for the entry, specified from a 0-based index. image0_url specifies the URL of the image, which will be resized to the maximum size of a thumbnail and stored on FriendFeed’s servers. If image0_link is not given, the thumbnail will link to the main link URL. If it is specified, the thumbnail will link to the specified image0_link.

Example usage with the FriendFeed Python library:

service = friendfeed.FriendFeed(nickname, remote_key)

# Publish a text message
service.publish_message("Testing the FriendFeed API")

# Publish a link
service.publish_link("Testing the FriendFeed API", "http://friendfeed.com/api/")

# Publish a link with thumbnail images
service.publish_link(
    title="Testing the FriendFeed API",
    link="http://friendfeed.com/api/",
    image_urls=[
        "http://friendfeed.com/static/images/jim-superman.jpg",
        "http://friendfeed.com/static/images/logo.png",
    ],
)

Example usage with curl:

curl -u "nickname:remotekey" -d "title=Testing+the+FriendFeed+API&link=http://friendfeed.com/" http://friendfeed.com/api/share

Upload Images with Entries

The /api/share method can also accept uploaded images encoded as multipart/form-data. This encoding is the standard used for file uploads within web browsers.

If any images are uploaded with the /api/share request, the original and the thumbnail are stored on FriendFeed’s servers, and the thumbnail is displayed with the entry.

By default, the thumbnails will link to the destination link for the entry. If you want each uploaded image to link somewhere else, you can specify the link in the IMAGENAME_link argument. For example, if your uploaded image is POST argument file0, you can specify the link for that thumbnail as file0_link.

Comment and Like Entries
/api/comment – Add or Edit Comments

A POST request to /feed/comment will add a comment or edit an existing comment on a FriendFeed entry. The arguments are:

    * entry – required – The FriendFeed UUID of the entry to which this comment is attached.
    * body – required – The textual body of the comment.
    * comment – If given, the FriendFeed UUID of the comment to edit. If not given, the request will create a new comment.

Example usage from the Python library:

service = friendfeed.FriendFeed(nickname, remote_key)
service.add_comment(
    entry="550e8400-e29b-41d4-a716-446655440000",
    body="Testing the FriendFeed API",
)

Example usage with curl:

curl -u "nickname:remotekey" -d "entry=550e8400-e29b-41d4-a716-446655440000&body=Testing+the+FriendFeed+API" http://friendfeed.com/api/comment

/api/comment/delete – Delete a Comment

A POST request to /feed/comment/delete will delete an existing comment. The arguments are:

    * entry – required – The FriendFeed UUID of the entry to which this comment is attached.
    * comment – required – The FriendFeed UUID of the comment to delete.

/api/like – "Like" an Entry

A POST request to /feed/like will add a "Like" to a FriendFeed entry for the authenticated user.

    * entry – required – The FriendFeed UUID of the entry to which this comment is attached

Example usage from the Python library:

service = friendfeed.FriendFeed(nickname, remote_key)
service.add_like("550e8400-e29b-41d4-a716-446655440000")

Example usage with curl:

curl -u "nickname:remotekey" -d "entry=550e8400-e29b-41d4-a716-446655440000" http://friendfeed.com/api/like

/api/like/delete – Delete a "Like"

A POST request to /feed/like/delete will delete an existing "Like." The arguments are:

    * entry – required – The FriendFeed UUID of the entry to which this comment is attached.

Authentication

If your application requires authentication, you use the following terminology FriendFeed nickname or email and Remote key in your login form. Your login form should contain a link to http://friendfeed.com/remotekey for users who have not memorized their key. It should open in a new window using target="_blank" so that the remote key page does not interrupt your application’s flow.