Dec 19, 2012

Salesforce to Fix Issue With Oauth 2.0 User-Pass Flow

We recently hit an issue with one of our clients where an external service was trying to authenticate against Salesforce with oauth 2.0 user-pass flow but kept receiving "unknown_error.retry your request" from Salesforce. We searched online and used #askforce but the only fix we found was to loging using the Salesforce instance, which does not work for us as we are trying to access Apex REST in a managed package that will be available on the AppExchange sometime soon.

So we opened a case through the partner portal which was quickly confirmed and escalated. Within a week, we receive a response that Tier 3 have identified the issue and that R&D is working on a patch that will likely to be released today (19th Dec 2012). They did not elaborate much further even though we prodded for some more geeky details, except to say that "the issue was due to internal issue" and that "the patch will be released on all instances".

Kudos to Salesforce for a quick turnaround!

Dec 18, 2012

Formula: Ref Tag for Email-to-Case

If you're using Salesforce for customer service, chances are that you are using email from the Case object.  When you leverage the "Email-to-Case" feature, Salesforce will add to Case related emails a "ref:" tag.

Let's assume is configured as your company's email-to-case Routing Address.  A customer needs assistance with one of your products and sends off an email requesting assistance.

This tag is what allows Salesforce to automatically connect this email to the appropriate existing case.  If not found, a new Case is created and set up in accordance with the configuration of that Routing Address.

So when the customer sends the email above, requesting assistance from, you're email server or email client will be configured to forward messages sent to to the Salesforce assigned email address, which looks like this:

When the email address is forwarded to the Salesforce address highlighted above, the Salesforce email services look at the subject and body of the message for an existing "ref:" tag.  If one is found, the email is created as Activity History for the associated case.  If one isn't found, it looks at the configuration of the Routing Address and creates a case.  This is why it is important to not remove the tag from your emails; doing so could result in duplicate or unnecessary cases.

There may be scenarios where you need to know what the "ref:" tag for a Case is.  You might need to include this on e-mail templates for internally created cases for customers.  

How is this value constructed and what is the Salesforce Email-to-Case email service expecting?

If you take a look at a "ref:" tag, you'll see it follows this pattern:

To replicate this in a formula field, you can use this:

I've seen a similar formula on the forums, but I've added a LEFT($Organization.Id,15).  Without this, I was generating the first portion of the "Ref:" tag using the 18 character ID of my org.  The resulting "Ref:" tag did not match the "Ref:" tag from the email I received in prior testing.

Now you can use the new formula field on your Salesforce templates.  Alternately, you can follow this patter when developing your own Salesforce email handling services.

Dec 11, 2012

Formula Example - What Day of the Week is/was it?

I found a post over at the Apex Code board at from someone who needed assistance creating a formula to determine how many Fridays occurred between two given dates.

Easy enough, I thought.  I'll just use a date method w/in a loop and count how many times Friday occurs.  I didn't find any date methods or dateTime methods that return the day of the week.  It seems like such a basic need; perhaps I glazed over it.

A quick Googlin' led me to one example, nearly 100 lines long.  It shouldn't be that difficult; I'd rather spend 100 lines showing you how to do the math and then 1 line of code using that math.

A little more poking around and this is what I found:

a = (x - y) (mod 7)

a = Day of the week index
x = a date in which you know the day of the week
y = the date in which you want to know which day of the week it was or will be

In a nutshell, figure out the number of days between your two dates (x and y), divide that number by 7, and the remainder (mod 7) will tell you the day of the week, based off of the known day of x.

We still need "x" - the copious amounts of calendar generators on the web all agree that 1/1/1900 was a Monday.  

Let's see it in practice, using 12/11/2012 as an example or proof (just pretend you don't know it's Tuesday).  12/11/2012 will serve as our "y" variable.

a = (12/11/2012 - 1/1/1900) (mod 7)
a = 41,252 (mod 7)
a = 41,252 divided by 7 leaves a remainder of 1
a = 1

Since we know 1/1/1900 was a Monday, we know that 1/2/1900 was a Tuesday, 1/3/1900 a Wednesday and so on all the way up to 1/8 when everyone has a case of the Monday's again.  There are 7 days between 1/8 and 1/1 and dividing 7 by 7 leaves you with a remainder of 0.  0 will represent Monday.  1/9/12 is a Tuesday and there are 8 days between 1/9 and 1/1.  Dividing 8 by 7 leaves you with a remainder of 1.  1 represents Tuesday.  The same logic tells you 2 is Wednesday, 3 is Thursday, 4 is Friday, 5 is Saturday, and 6 is Sunday.  In the example above, a = 1, therefore 12/11/2012 must fall on a Tuesday.

So all we need to do now is plug in our dates and use a few methods that do exist.

We'll use:

Go ahead, try executing that code and seeing what the debug output tells you.

So now we have an easy mechanism for determining the day of the week for a given date. Let's go the extra mile and see how we can easily create a bit of code now that determines how many how many of a certain day occurred between two dates.

Dec 6, 2012

Salesforce Mobile SDK - Xcode Setup and iOS App

This is part three of the Salesforce Mobile SDK Series.  Have you read parts one and two yet?

  1. Salesforce Mobile SDK - Introduction
  2. Salesforce Mobile SDK - Mobile Visualforce Page and the Connected App

So far we've learned the differences between native, hybird, and HTML5 apps, how to create a mobile Visualforce page, and how to create a Connected App to get our crucial Consumer Key and Secret.  The next step takes what you've done and turns it into a mobile app.  By the end of this post, you'll have an iOS app that handles authentication and delivers a multipage experience.

Before you get started working with the Salesforce Mobile SDK, you'll need to set up your Mac environment.

1)  Boot up your Mac and install Xcode from the App Store.

2)  While that's downloading (it'll take a while), download and install GitHub:

3)  Pull in a local copy of the SalesforceMobileSDK-iOS project by using the "Clone in Mac" button here:

4)  While you're waiting, you'll want to clone the MobileComponents as well:

5)  Launch a Terminal window (Finder --> Applications --> Utilities --. Terminal) and navigate to the cloned SalesforceMobileSDK-iOS folder, presumably in your home directory.  
  • cd ~/SalesforceMobileSDK-iOS
  • sudo ./
  • sudo cd ..
  • sudo chown -R YourUserName SalesforceMobileSDK-iOS
6)  By now, Xcode should have downloaded and installed.  If not, wait for that to happen, then launch it (Finder --> Applications --> Xcode).

7)  If you've never launched Xcode before, you'll land on this screen.  Click on "Create a new Xcode project" if prompted and if not, click on File --> New --> Project...

8)  From the menu, choose iOS --> Application, highlight the "Hybrid App" icon, and then click on the "Next" button

9)  Provide the following details about your new app and then click on the "Next" button.  You can get the "Consumer Key" and the "Redirect URL" from within your Salesforce org by clicking on the "Setup" link and navigating to Create --> Apps --> Your Connected App Name.  For more details on creating the "Connected App," see part two of this series.

10)  You'll now be prompted to choose a location to save your project file.  Navigate to your location of choice and click on the "Create" button.

11)  Once your project is created, highlight the "WWW" folder, right-click on it, and choose "Delete." 

12)  When prompted, click on the "References Only" button.

13)  Highlight your root project folder, right-click, and choose "Add Files to "Your Project"..."

14)  Navigate to your project directory, highlight the "WWW" folder, and then click on the "Add" button.

15)  Expand the "WWW" folder in your project browser and click on bootconfig.js.

16)  Find the line that begins with "var startData..."  This tells the application which page to load after authentication.  

Since we are building a hybrid app, we'll comment out the first line, uncomment the second line, and modify the path portion to reference the Visualforce page we created in part two of this series.

17)  Now it's time to make sure the app runs.  Make sure all of your changes have been saved, and then click on Product --> Run.  This will start up either an iPad or iPhone simulator and with any luck, request your Salesforce credentials:

18)  Enter your credentials and click on the "Login" button.  The app will then prompt you to provide permissions.  Click on the "Allow" button to continue.

After clicking on the "Allow" button, you'll see your mobile VF page.  If you tap/click around, you'll notice the interface and page navigation looks and feels like a native app.

In the next and final post of this series, you'll learn how to set up your Eclipse environment and use the the same Visualforce Page and Connected App to create an Android app.

Dec 4, 2012

iPad-less Salesforce Touch Testing

Salesforce Touch became generally available in the Winter '13 release.  It is available in the Contact Manager, Group, Professional, Enterprise, Unlimited, and Developer Editions and according to the requirements, currently supports Apple iPads (2nd and 3rd generation) with iOS version 5 and up.


Unfortunately, not everyone has an iPad to access, test out, or even debug the new Touch interface.  Fear not, a simple change in your browser settings will allow you nearly the same access.

First, make sure that you have the new "Touch" feature enabled for your org and the users that you want to test with.

1)  Log into Salesforce and access the "Setup" menu:

2)  Under "Administration Setup," expand "Mobile Administration," "Salesforce Touch" and then click on "Settings:"

3)  Ensure that the "Enable the Salesforce Touch mobile browser app" setting is enabled

4)  Next, ensure that Touch is enabled for the user account you are testing with by expanding "Manage Users" under "Administration Setup" and clicking on "Users:"

5)  Find the relevant user(s) and ensure that "Touch User" is enabled:

Now that "Touch" is enabled in all of the right places, it's time to change your browser's user agent, effectively allowing your browser to mimic Safari.  Here's how to do that in Chrome.

1)  Log out and change your URL to ""

2)  Click on Chrome's "Settings" button and navigate to Tools -> Developer Tools (Shift+CTRL+I)

3)  Click on the Developer Tools settings button (the gear icon) in the bottom-right hand corner

4)  Click on the "Overrides" tab

5)  Ensure that "User Agent" is checked and choose one of the "iPad --iOS" profiles

6)  Refresh your Salesforce Login window and it should now look like this:

If you're familiar with the Salesforce Mobile SDK, this will look familiar to you.

Take note that if you are logging in with an account with an Administrator profile, you will not experience the Salesforce Touch interface after logging in, but will rather be redirected to the normal "Setup" page.

If anyone has a one of those new, shiny, touchscreen Windows 8 machines, I'd love to hear if the interface is "Touchable."

Not using Chrome?  Here's a link that may include information on how to change your user-agent setting w/in your browser of choice.

Nov 29, 2012

Formula Example - Days Until Quarter's End

Today I bring you two ways to accomplish the same thing; display the number of calendar days until the end of the quarter. You probably wouldn't use these formulas to create a field (why show the number of days on every record?), but might use on a Visualforce page or email template. You may even modify them to enhance a validation or workflow rule.

The first way uses a series of nested IF() functions whereas the second way demonstrates how to arrive at that number using a CASE() function. The CASE way has a small work around in it, explained below.

Using nested IF functions:

Typically a CASE function follows this pattern: CASE(expression,​value1, result1, value2,​ result2,...,​ else_result) which leaves very little room for additional criteria. Expression is usually the field you will look at the value of, valueX will be the value to look for, and resultX will be the text to display if valueX and resultX match.

The issue we have is valueX will be any date between a given quarters start and end dates (displayed within the AND()s below). Nothing prevents us from giving an expression of "1" (aka TRUE) and then providing the values as IF statements that return 1 or 0. We just need to ensure that the datatypes compared match and the criteria doesn't overlap as the first to return 1 or TRUE ends our CASE function.

Using the Case function w/ workaround:

Nov 28, 2012

Salesforce Mobile SDK - Mobile Visualforce Page and the Connected App

This is part two of the Salesforce Mobile SDK Series.  Part one is here:  Salesforce Mobile SDK - Introduction

There's one common component between Android and iOS development when creating a hybrid app and that's the Visualforce page.  This ability to code it once and use it multiple places was repeatedly touted at Dreamforce '11 and '12.  This post will briefly go over the creation of such a page as well as the creation of a Connected App.

"Connected App" is an application that can connect to over Identity and Data APIs. Connected Apps use the standard OAuth 2.0 protocol to authenticate, provide Single Sign-On, and acquire access tokens for use with Salesforce APIs...  (read more)

1)  Our simple page will take advantage of a few external files, a .CSS file, and two .js  found in the CloudTunes sample included within the SalesforcemobileSDK-Samples package.  Grab the Static Resource named "cloudtunes_jQuery.resource" and it's accompanying meta.xml from here:

2)  Open Eclipse/ IDE and create a new project for your mobile Visualforce project

3)  Copy cloudtunes_jQuery.resource and cloudtunes_jQuery.resource-meta.xml into your project, creating the "staticresources" folder if needed:  ../Workspaces/ProjectFolder/Project/src/staticresources/

4)  Jump back over to your IDE, right-click on your "src" folder and click on "Refresh" to pick up the new files.

5)  Save the Static Resource to the server by right-clicking on your "src" folder within the project explorer, going to "" and clicking on "Save to Server."

6)  Now create a new Visualforce page by right-clicking on your project --> New -- > Visualforce Page.  Give it a name and click on the "Finish" button.

7)  Below is how I've structured my page.  Take note of the different div data-role's.  Although I'm only creating one Visualforce page, my final product will have four different "screens" (Main, About CRM Science, Ami, and Kirk).

Now that we have the page, it's time to create a "Connected App" within our Salesforce org.  Again, a "Connected App" is defined as an app that leverages the Identity and Data APIs to connect to Salesforce.  If you're familiar with "Remote Apps," Connected Apps are meant to be an updated replacement, including additional features giving you the power to limit who can use the app and which security policies are used by the app.  After the app is created, we'll also receive our Consumer Key and Secret values that are used when creating the hybrid app in Xcode or Eclipse.

Configuring a custom app is a straightforward process.  First you define the OAuth metadata with details like the app name, description, callback URL, operational IP range (optional), as well as info about enforceable mobile policies (also optional).

1)  Navigate to Setup -->  App Setup --> Create --> Apps and click on the "New" button within the "Connected Apps" section.

2)  Provide the "Basic Information" for your app.

3)  Next, define the details for the API Integration.  For the Callback URL, I've defined "testsfdc:///mobilesdk/detect/oauth/done" and selected the "Access your basic information" OAuth scope.

4)  Click on the "Save" button and you'll be taken to your new Connected App's record.  Notice the Version, Status, Consumer Key, and Consumer Secret fields.

Now you're ready to begin your hybrid app "development."  In the upcoming posts, you'll see how to configure your dev environments (Xcode or Eclipse) and how to use the Salesforce Mobile SDK to take advantage of the power of your Visualforce page.

Nov 21, 2012

Salesforce Mobile SDK - Introduction

It's hard to avoid the excitement that is being generated as a result of's mobile SDK. If you made the pilgrimage this September to Dreamforce in San Francisco or braved the rain at this month's Cloudforce in New York, you may have surely been exposed to the mobile SDK in one way or another. This year's Dreamforce App took advantage of the Salesforce Touch Platform. Several of the sessions at both events demonstrated just how easy it was to develop an app for both the Android and iOS platforms while minimizing the amount of code that had to be rewritten.

Using the Salesforce Touch Platform, you can develop apps in three ways - each has their own unique advantages and disadvantages.

Coding is specific to the platform, meaning your using the traditional development tools and languages used in iOS and Android development. This approach requires you to be well versed in Objective-C for iOS, Java for Android, and to be able to navigate their respective environments, Xcode and Eclipse. Once developed, these apps are packaged and made available on the platforms' app market places.

Using stadard web technologies, like HTML5, Javascript, and CSS, web pages are created to mimic the look and feel of native apps. However, these are not downloaded from the platforms' app market places, but are accessed via the mobile device's browser. Many of the device's native hardware functions are not accessible using this approach.

Using the hybrid approach, you can take advantage of the write-once-run-anywhere philosophy and wrap an HTML5 page (or Visualforce page) within a native app container while having access to a device's hardware capabilities, without needing to know Objective-C or Java.

Over a series of posts to follow, I will detail the creation of an HTML5 based Visualforce page and how to generate both an Android and iOS app, using the same page. These posts will also detail the steps required to setup both development environments.

Nov 20, 2012

Formula Example - Case Days Open

Today's Formula calculates either the number of days a case was open before being closed or the number of days the case has been open since it was created.

This formula uses 3 different functions:
  1. IF(logical_test, value_if_true, value_if_false) - Determines if expressions are true or false. Returns a given value if true and another value if false.
  2. ROUND(number, num_digits) - Returns the nearest number to a number you specify, constraining the new number by a specified number of digits.
  3. NOW() - Returns a date/time representing the current moment.

Here's a Case view that displays two cases, both open and closed, the fields referenced by the above formula and the formula field itself (# of Days Open).

Nov 12, 2012

Using Business Time to Set Workflow Task Due Date

A couple of weeks ago I posted a hack that enables assigning a workflow task to a related user on the triggering object. This works with a class called WorkflowInstructions that parses a task descriptions and looks for a familiar string format (a "workflow instruction"). Once a workflow instruction is found, the class processes the workflow task according to the instructions.

Since the code allows processing of several types of workflow instructions, here is another useful use case... setting activity cto a certain number of business days from the case create date. For some reason, business hours is available in apex, but not when setting workflow tasks.

So here is what you need to add to the previous post code sample:
  • Add a business hours variable to hold your selected business hours record.
  • add 'businesstime' when checking for workflow instructions.
  • add a method that processes the 'businesstime' workflow instruction.

You still need the code for the trigger as in the previous post: And now, all you have to do to make the workflow work is to set up the workflow instruction in the description of the workflow task. The trigger will fire, then change the task activity due date, and then remove the instruction from the description. here is an example:

Nov 6, 2012

Using Bucket Fields for Organized Reporting

Up until the Spring '12 release, if you wanted to categorize data within your reports, you had to create additional formula fields to do your classifications and then pull these new fields onto your report. With the advent of reporting buckets, you can easily categorize records within your reports on the fly, directly from the report builder screens.

For this example, let's say you have a set of Account records, each having the standard currency field "Annual Revenue" populated. For reporting purposes, you want to categorize your Account records into three different tiers.

Gold: Annual Revenue > 3,000,000
Silver: Annual Revenue between 1,000,000 and 3,000,000
Bronze: Annual Revenue below 1,000,000

Before buckets were introduced, you may have created a formula field that looks like this:

While this works, you've just created a field for this very specific purpose.

Bucketing can help you (and your non-admin employees) more efficiently do the same by following these steps:

1)  To create a new Bucket field, within a new/existing report, click on the "Add Bucket" link within the fields section.

2)  Next, specify a source field in the "Source Column," give your Bucket field a name, and define your ranges:

3)  Click on the "OK" button and you'll see your newly created "Service Level" field within your report grid:

Unfortunately, the current bucketing offering lacks the ability to create and use filters.

What if you had a client that has been with you from day one. Sounds like instant "Gold" level client criterion to me. It would be great to be able to include additional criteria, in this case something like "Initial Contract Date < 1/1/2005" = Gold, to the bucket calculations.

Additional Information: 
Bucketing in Reports:
Categorizing Data Quickly with Buckets:

Oct 29, 2012

Assigning Workflow Task Owner to a Related User

I recently had to come up with a way to assign a workflow task to a related user on the triggering object. That functionality is not available Since a workflow task can only be assigned to the record owner, a specific user or a role. The object that causes the workflow to fire has several user lookup fields, and based on specific events, one of the users specified by these fields needs to be set as the assigned user for the task that is created by the workflow.

I decided to use a trigger on the task object to get the job done. I also decided to write the code in a pretty generic way because I think that there may be other uses for this piece of code. So what I did is create a class called WorkflowInstructions that parses the task description, looking for a familiar string format (a "workflow instruction") and based on what it finds, do something (in this case, assign the task owner to a related user on the originally fired object). Not sure I am doing a good job explaining this in words, so lets get to the actual code...

So now that we have a nice generic class,here is the code for the trigger:
And now, all you have to do to make the workflow work is to set up the workflow instruction in the description of the workflow task. The trigger will fire, change the owner of the task to the related user, and then remove the instruction from the description. here is an example:

Sep 24, 2012

Sep 12, 2012

AppExchange Listing DevZone Session at Dreamforce

I am now going to lead a DevZone session at dreamforce about the AppExchange listing process. I am going to use a blog post I wrote a few months ago as a rough agenda, and hope to share a more personal account of my experience in this area. 

Here is the official Dreamforce session info:

Step By Step Guide To Salesforce AppExchange Listing
When: Wednesday, September 19th: 4:30 PM - 5:30 PM
Where: Moscone Center West, DevZone Unconference A
Description: Developing and packaging apps is not that complicated, if you already have experience with SFDC or know what to look for. However, starting a provider relationship with Salesforce and navigating through all the orgs, requests, cases, and account execs is a complex and confusing process. This is an account of a recent AppExchange listing.

Click here to see this session in the Dreamforce App, and to join the conversation on Chatter.

Sep 4, 2012

Apex Testing Session at Dreamforce 2012

One of the sessions I am leading at Dreamforce 2012 is about Apex testing. A fellow PhillyForce leader Matthew Botos came up with the idea for the session, but he ended up not being able to go, so now Wes Nolte and I are going to present the session. The session discusses a typical mini project that many of us have come across in the past, and provide a few tips to improve your testing code. The session has some really useful information and will introduce a couple of great tools that you can keep in your toolbox.

We are going to cover three topics:
  • Automation of test data creation with SmartFactory.
  • Implementing web callouts with an interface to improve testing. 
  • Continuous integration with automated test runs. 

Here is the official Dreamforce session info:

Top Testing Tips: Data Creation, Web Callouts, and Automation
When: Tuesday, September 18th: 4:00 PM - 5:00 PM
Where: Moscone Center West, 2024
Description: Take your Apex code testing to the next level with sample code and open source libraries that make these advanced topics easy. Save time with SmartFactory, which automatically creates complex test data for tests isolated from your regular data. Learn how to test web callouts cleanly and completely using interfaces and mocks. Finally, make sure all your team's tests run regularly with native automation that takes a fraction of the time of full continuous integration.

Here is where you can follow this session on Chatter.

Aug 29, 2012

Aug 27, 2012

Chatting About Salesforce User Groups at Dreamforce

It looks like Salesforce is taking its "It's Social" slogan to heart with a renewed effort to support Salesforce and user groups around the world. For example, current user group leaders can now belong to an invitation only meetup group that is designed to foster discovery of best practices and help us grow our local communities. I think that being more proactive in providing assistance to local user groups like PhillyForce is a great move by Salesforce, and would be a huge help for us in the trenches!
During Dreamforce next month there will be a couple of session that will discuss user groups. I am going to present one of these sessions, and will talk about reasons why I chose to be involved and what user group leaders do on a regular basis.
So, if you are interested in becoming more involved in your local Salesforce community, or thinking of starting a user group in your home town, join me for an informal session on the last day of Dreamforce. I look forward to see you there!
Here is the official Dreamforce session info:

Get Connected with your Local Salesforce Platform Developer User Group
When: Friday, September 21st: 9:30 AM - 10:00 AM
Where: Moscone Center West, Community Common
Description: Are you part of your local Developer User Group? Curious about how they work and wondering how one could benefit you? Join us to hear from current Developer User Group Organizers on why they got involved with a user group and what their groups are like. Learn how you can tap into the local developer community to expand your Salesforce Platform resources.

Here is where you can follow this session on Chatter.

Jun 11, 2012

Some More Cool Summer '12 Features

Last week, I listed my Top 5 Summer '12 Features, but there are several other features that I think are worth mentioning, including some non-development enhancements...

Salesforce Touch Beta
Other than the marketing videos, I haven't seen this HTML5 site in action so I am not sure how good it is. I assume that it is better than the current mobile options that Salesforce provides, so I am looking forward to checking it out. The web version of Touch will be available in all orgs by June 8. and the Touch App will be available from the Apple App Store later this summer. More detail here.

Single View State is GA
All forms are now merged into a single view state. This enhancement is very important if you include several custom components in Visualforce pages. Until now, each apex:form tag translated into its own view state, which increases the data sent to the client and reduces performance. More detail here.

Chatter Messenger is GA
As an SFDC consultant, I do a lot of my work remotely, so I use Skype A LOT for chat, voice and video conferencing. I can see how Chatter Messenger could replace my Skype usage in some cases because I am already in Salesforce all the time (although I often switch between orgs). For mid to large organizations, I see it as a great plus as users can get answers without getting up, which always increases productivity. With that said, I have to say that I don't like the location of the messenger tab - I think it should be moved to the header because it hides some of the data at the bottom, which is not great. More detail here.

Re-parenting of Master-Detail Fields
I never understood why this behavior was not the default to begin with, but thankfully, you can now specify if a master-detail field can support re-parenting. I needed that option several times in the past, so I am glad it is available now. More detail here.

Jun 6, 2012

Top 5 Summer '12 Features

Since Summer '12 will hit production orgs this week, I decided to list my favorite new development-related features in this release. I like these particular features because I either needed them in the past (and had to find workarounds instead) or feel that the new feature substantially improves current functionality. This is a very short list of features, just things that made me happy. For the complete list, download the release notes or check out the various release videos.

Update: see some more things I like in Summer 12 in this later post. 

Multi-relationship Activities
Did you ever go to an event and meet only one person? Until the addition of the new "Shared Activities" feature, you could only associate one contact to a specific activity. This is not really a feature but it will definitely change how I program around tasks and events. For as long as I've been working on Salesforce, I've always tried to make it less hierarchical and more relational. The addition of the new "Shared Activities" feature plugged a big hole and should allow for much more streamlined tracking. This is a good start - I hope that in time, Salesforce would create a more dynamic association to activity by as many record as needed and to any type of object. Note that this feature is not turned on automatically - you have to got to Activity Settings and select "Allow Users to Relate Multiple Contacts to Tasks".

Offset SOQL Statement is GA
If you create list components as much as I do, you can probably appreciate this new feature. This will help with list paging as well as give new ways to work around limitations of large fetches. More detail here.

Lookup Fields Improvement
This is a great little update. First, you can now specify whether a lookup field is required or not, which was not possible previously. And Second, you can also select from two new options to handling the record on parent deletion - either restrict parent deletion if a lookup relationship exists or cascade delete like master-detail relationship. This update will work well in the cases that you want to cascade deletes but don't want to make the lookup required. More detail here.

Package Install Handlers
Managed packages will now have the ability to include Apex code that runs after install, uninstall or upgrade. This is a great feature for those of us who are building AppExchange apps because until now, you had to wait for a user action to make org or user-specific configurations. More detail here.

Metadata REST API Pilot
Although this new API is going to be very limited (read only), I am excited about its potential. I think it will enable developers to build new and better development tools as alternatives to the Eclipse plugin and the online development interfaces, none of which are great to work with. It may also be an easier way for app developers to perform administration and configuration tasks from outside salesforce. More detail here.

Update: see some more things I like in Summer 12 in this later post.