INTEGRATING PARDOT AND SALESFORCE – USER INTERFACE LAYER

I recently wrote a blog post about ‘Integrating Pardot and Salesforce – Data Layer’.  That is great that we can make that web-service call to Pardot, and Salesforce helps us to make that call in just a few lines.  But once we get that data back how do we get it back to a Visualforce page?

Today I would like to share a recipe for doing just that.  Take some xml data, parse it and get it back to an ‘apex:datatable’ on a Visualforce page.

Here is what we are going to need for our recipe…
1) A Visualforce page to show the table of Pardot data.  This Visualforce page will use the Contact StandardController so the Visualforce page can be added as an in-line Visualforce page to the standard page layout.
2) An Apex class to do the Pardot API call and to parse the response
3) Another Apex class that is specifically used to hold the Pardot data so that it can be bound to the page.

Here are the directions for putting all of this together.
1) Create an Apex class that can parse the XML (or JSON) data that is returned from Pardot and then put that data in another class that can be used to bind to the Visualforce page.
We already had a class from the last blog post that was doing the code to get the XML from Pardot.  Here is some code to loop through the XML returned from Pardot and to pull out the Prospect’s Activities.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
       //The whole goal is to fill this instance variable on the class so that it can be bound to the Visualforce page
       public list<PardotActivityData> PardotActivityDataList{get;set;}
       //This class will get bound to the apex:datatable on the Visualforce page
       public class PardotActivityData{
         public string activityName{get;set;}
         public string activityLink{get;set;}
         public string activityType{get;set;}
         public string campaignName{get;set;}
         public string campaignLink{get;set;}
         public string score{get;set;}
         public string dateTimeValue{get;set;}
         public dateTime dtValue{get;set;}
     }
       public void getPardotData(){
             //There is code up here to make the actual Pardot call
            string sTemp ='';
    string campaignName ='';
    string campaignID ='';
    prospectData = bodyReturn; //bodyReturn is the XML returned from Pardot
    activityItems = PardotDetails.getValueFromXMLString(bodyReturn,'visitor_activities');
    PardotActivityDataList = new list<PardotActivityData>();
    PardotActivityData paItem;
    list<string> activityItemList = new list<string>();
    activityItemList = PardotDetails.retrieveListBySplit(activityItems,'visitor_activity');
    for(string s : activityItemList){
      //<visitor_activity> <id>13997947</id> <type>19</type> <type_name>Opportunity Associated</type_name>
      // <opportunity_id>234409</opportunity_id> <created_at>2014-09-03 11:49:16</created_at> </visitor_activity>
      paItem = new PardotActivityData();
      paItem.activityName = PardotDetails.getValueFromXMLString(s,'type_name') + ': ' +
         PardotDetails.getValueFromXMLString(s,'details');
      paItem.activityLink ='https://pi.pardot.com/opportunity/read/id/' + PardotDetails.getValueFromXMLString(s, 'opportunity_id');
      paItem.activityType = PardotDetails.getPardotType(PardotDetails.getValueFromXMLString(s,'type'));
      paItem.campaignName =''; //<campaign> <id>572</id> <name>Website Tracking</name> </campaign>
      paItem.campaignLink ='';
      sTemp = PardotDetails.getValueFromXMLString(s,'campaign');
      if(string.isBlank(sTemp) == false){
         paItem.campaignName = PardotDetails.getValueFromXMLString(s,'name');
         campaignID = PardotDetails.getValueFromXMLString(s,'id');
         paItem.campaignLink ='https://pi.pardot.com/campaign/read/id/' + campaignID + '/campaign_id/572' + campaignID;
      }
      paItem.score =''; //How do I get the score for Activities out of the API?
      paitem.dateTimeValue = PardotDetails.getValueFromXMLString(s,'created_at');
      try{
        paitem.dtValue = dateTime.valueOf(paitem.dateTimeValue);
                paitem.dtValue = dateTime.newInstance(paitem.dtValue.dateGMT(), paItem.dtValue.timeGMT());
      }catch(exception e){
      }
      PardotActivityDataList.add(paItem);
    }
           }
           public static string getPardotType(string typeValue){
    if(string.isBlank(typeValue)){
        return'';
    }
    if(typeValue =='1'){
        return'Click';
    }else if(typeValue =='2'){
        return'View';
    }else if(typeValue =='3'){
        return'Error';
    }else if(typeValue =='4'){
        return'Success';
    }else if(typeValue =='5'){
        return'Session';
    }else if(typeValue =='6'){
        return'Sent';
    }else if(typeValue =='7'){
        return'Search';
    }else if(typeValue =='8'){
        return'New Opportunity';
    }else if(typeValue =='9'){
        return'Opportunity Won';
    }else if(typeValue =='10'){
        return'Opportunity Lost';
    }else if(typeValue =='11'){
        return'Open';
    }else if(typeValue =='12'){
        return'Unsubscribe Page';
    }else if(typeValue =='13'){
        return'Bounced';
    }else if(typeValue =='14'){
        return'Spam Complaint';
    }else if(typeValue =='15'){
        return'Email Preference Page';
    }else if(typeValue =='16'){
        return'Resubscribed';
    }else if(typeValue =='17'){
        return'Click (Third Party)';
    }else if(typeValue =='18'){
        return'Opportunity Reopened';
    }else if(typeValue =='19'){
        return'Opportunity Linked';
    }else if(typeValue =='20'){
        return'Visit';
    }else if(typeValue =='21'){
        return'Custom URL click';
    }else if(typeValue =='22'){
        return'Olark Chat';
    }else if(typeValue =='23'){
        return'Invited to Webinar';
    }else if(typeValue =='24'){
        return'Attended Webinar';
    }else if(typeValue =='25'){
        return'Registered for Webinar';
    }else if(typeValue =='26'){
        return'Social Post Click';
    }else{
        return'';
    }
}
  private staticString getValueFromXMLString(String xmlString,String keyField) {
    String valueFound ='';
    if(xmlString.contains('<' + keyField + '>') && xmlString.contains('<!--' + keyField + '-->')){
        try{
            valueFound = xmlString.substring(xmlString.indexOf('<' + keyField + '>') + keyField.length() + 2, xmlString.indexOf('<!--' + keyField + '-->')); 
        }catch (exception e){
            system.debug('Error in getValueFromXMLString.  Details: ' + e.getMessage() + ' keyfield: ' + keyfield);
        }           
    }
    return valueFound;
}
private static list<String> retrieveListBySplit(string splitMe, string splitValue){
    string sTemp ='';
    list<string> returnListTemp = new list<string>();
    list<string> returnListFinal = new list<string>();
    if(string.isBlank(splitMe)){
        return returnListFinal;
    }
    splitMe = splitMe.trim();
    returnListTemp = splitMe.split('<!--' + splitValue + '-->');
    for(string s : returnListTemp){
        s = s.trim();
        if(s.startsWith('<' + splitValue + '>')){
            sTemp ='<' + splitValue + '>';
            s = s.substring(sTemp.length());
        }
        returnListFinal.add(s);
    }
    return returnListFinal;
}

2) Create a Visualforce page that uses the Contact StandardController.  Here is a page that will fit with our controller.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<apex:page standardcontroller="Contact" extensions="PardotDetails" showheader="false" sidebar="false">
    
    <apex:pageblock title="Prospet Activities">
        <apex:pageblocktable value="{!PardotActivityDataList}" var="item" width="100%">
            <apex:column headervalue="Activity">
                <apex:outputlink value="{!item.activityLink}" id="activitylink1" target="_top">{!item.activityName}</apex:outputlink>
            </apex:column>
            <apex:column value="{!item.activityType}" headervalue="Type">
            </apex:column>
            <apex:column headervalue="Campaign">
                <apex:outputlink value="{!item.campaignLink}" id="campaignlink1" target="_top">{!item.campaignName}</apex:outputlink>
            </apex:column>
            <apex:column value="{!item.score}" headervalue="Score">
            </apex:column>
            <apex:column headervalue="Date / Time">
                <apex:outputtext value="{0,date,MMM dd,yyyy hh:mm a}">
                <apex:param value="{!item.dtValue}"></apex:param>
                </apex:outputtext>
            </apex:column>
        </apex:pageblocktable>
    </apex:pageblock>
</apex:page>

Notice how the Visualforce page uses the StandardController=“Contact” syntax so it can be added to a standard page layout.  The Apex class that we created is then referenced in the extensions=“PardotDetails” attribute.  Notice how the “Date / Time” column is formatted too.  The date/time value returned from Pardot I think is in GMT time so it may be a bit of work to make sure that your Salesforce time zone matches up with your Pardot time zone.

That really does it.  The page should show you Prospect activities for the Prospect in Pardot that matches by email address of the Contact record in Salesforce.  You just have to pull the email address from the Contact record using the Standard Controller methods in the constructor of your class.

In-line Visualforce pages are great for this type of integration where it is read-only data.  Good luck with your next integration!

Posted in Technology | Tagged , , , | Leave a comment

INTEGRATING PARDOT AND SALESFORCE – DATA LAYER

Pardot has had a couple of big changes in the last couple of years.  It was first bought by ExactTarget back in October 2012 for $95.5 million.  It was not more than 8 months later in July of 2013 that Salesforce then bought ExactTarget, which of course then included Pardot also.  Now we are here today in September of 2014 and it is already amazing how easily pieces of Pardot and Salesforce can be integrated together.

Salesforce is already a great platform for integrating with solutions and systems outside of it with its support for external callouts, outbound messages through workflow rules, the ease of building REST/SOAP web services to call into Salesforce and the out-of-the-box Partner and Enterprise APIs.  There are even many more options that I do not have time to list here.

Pardot already has an AppExchange offering that should cover most simple integrations scenarios with Salesforce.  But there are always unique requirements and wishes that customers will come up with surrounding any integration.

But for today we want to leverage the ability to make an external callout to the Pardot API in order to pull in activities from a Pardot Prospect.  In a future blog post I will write about interacting with the Visualforce page for the user interface piece, but for this post I just want to focus on the mechanics of making the API call itself.

Here is an Apex method that will make the API call to Pardot.  Make sure that you have addedhttps://pi.pardot.com as a Remote Site Setting.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public void getPardotData(){
        String user_key ='';
        String bodyReturn ='';
        HttpRequest req = new HttpRequest();
        HttpResponse res = new HttpResponse();
        Http http = new Http();    
        String email ='';
                 
        //user_key is the'API User Key' field on the 'Settings' page in Pardot
         // Ensure that the specified user account has at least"Marketing" access privileges.
         user_key ='YourUserKeyHere'; //The 32 character hexadecimal user key for your user account
        email ='name@emailAddress.com';  //The email address of the Prospect in Pardot.   This can be retrieved from the Salesforce contact record if that is what is matching up.
 
        req.setEndPoint('https://pi.pardot.com/api/prospect/version/3/do/read/email/' + email + '?');
        req.setBody('api_key=' + apiKey +
                    '&user_key=' + user_key +
                    '&email=' + email +
                    '&output=full' +  //full/simple/mobile - Default is full
                    '&format=xml');
                            
        req.setMethod('POST');
            res = http.send(req);
        bodyReturn = res.getBody();
}

This link shows how to make this query call on the prospect and what the format of the XML will look like that is returned.

You need a Pardot account and a Salesforce Org to make this example work.  Some interesting pieces of the code above are….
1) Notice the ‘email’ at the end of the URL in the ‘setEndPoint’ line.  You can query based on the email of the prospect or by the ID of the Pardot prospect.  Just like in Salesforce the ID of the Pardot prospect can be seen in the URL.
2) The api_key being used can be found by going to your ‘Settings’ page in Pardot.
3) The ‘output’ parameter can be full, simple or mobile.  It is great to be able to set this to mobile so that a smaller subset of data can be returned if you are working with limited resources.
4) The ‘format’ parameter can be xml or json.

Here is the routine to get the apiKey, which is an instance variable on the class above.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public void loginToPardot() {
        
        String user_key ='';
        String password ='';
        String email ='';
        String bodyReturn ='';
        HttpRequest req = new HttpRequest();
        HttpResponse res = new HttpResponse();
        Http http = new Http();    
        loginErrorMessage ='';
        apiKey ='';
                 
        //user_key is the'API User Key' field on the 'Settings' page in Pardot
        // Ensure that the specified user account has at least"Marketing" access privileges.
        user_key ='YourUserKey'; //The 32 character hexadecimal user key for your user account
        password ='YourPassword'; //The password of your user account
        email ='yourEmail@YourDomaincom';  //The email address of your user account
 
        req.setEndPoint('https://pi.pardot.com/api/login/version/3');
        req.setBody('email=' + email +
                    '&password=' + password +
                    '&user_key=' + user_key);  
                            
        req.setMethod('POST');
        res = http.send(req);
        bodyReturn = res.getBody();
                apiKey = PardotDetails.getValueFromXMLString(bodyReturn,'api_key');   
     }

There is a lot more error checking that should be added to this routine, but the login routine should get you started.

It is as simple as that.  With one small routine we can get connected to the Pardot API and start pulling back any type of Pardot data that we want.

Please let us know if Sundog can help you with your next integration project.

Posted in Technology | Tagged , , , | Leave a comment

10 REASONS TO WATCH: CUSTOMER JOURNEY LIVE WEBINAR

Want to walk a mile in your customer’s shoes? Let us take you a whole lot further.

You’re invited to join us for a new webinar series called “The Extra Mile: Step Up Your Customer Journey.” The first one starts Tuesday, September 16 at 11:30 am CT, and you canregister right here.

Top 10 Reasons to Watch
Why tune in? Well, here’s a list of our 10 favorite reasons.

  1. You’ll discover what the customer journey is, what it isn’t and why it matters to your organization.
  2. Our presenters are wildly entertaining. Really.
  3. They also know their stuff – with deep expertise in market research, healthcare, manufacturing and more.
  4. You’ll hear lots of real-world examples about what does (and doesn’t) work.
  5. Gain insights into how customer personas, segmentation and maps are created.
  6. See why the customer journey can be a catalyst and tool for change.
  7. Learn how it can help you create great brand experiences consistently – and on a bigger scale across departments and locations.
  8. You’re busy. Trust us – we understand. That’s why our webinar is scheduled over the lunch hour, so you can multi-task. All without missing a step.
  9. Yep, it’s free. (Enough said.)
  10. Watch it as a conversation-starter with your team. It’s a terrific opportunity to discuss where your company stands. And where you want to go.

Want to learn more? You can check out our speakers, along with more info and blogs about the customer journey. See webinar details & preview >

Hope you can make it!

Posted in Technology | Tagged , , , | Leave a comment

MEET OUR #DF14 SPEAKERS

Going to Dreamforce 2014?

Come meet a couple of Sundoggers who are packing their bags for San Francisco. This year, two of our high-tech experts have been invited to speak in the Developer Zone. In their sessions, you’ll find lots of real-world insights to hit the ground running with the Streaming API and maximizing VisualForce. Not to mention, they’re a couple of the coolest guys you’ll find at #DF14.

(And if you don’t speak geek, don’t worry. You’re still invited to walk a block to our Basecampfor free cocktails, coffee and everything else you need to recharge – yourself and your devices.)

Our #DF Speakers & Sessions

CHRIS KULISH
Chris Kulish
+ brilliant software engineer
+ over 10 years of dev experience
+ interested in writing complete apps with Javascript
+ proud papa of three boys
+ brews his own beer
+ learning to play the bagpipes (really)

Building Visualforce Pages with AngularJS and JavaScript Remote Objects
Bridging the gap between current browsers and future web technologies is vital in our ever-changing world. Visualforce is a simplified yet powerful method for building web apps capable of accessing data functions to maximize user interaction. This session will provide the framework for building pages with AngularJS and Visualforce Remote Objects by removing the complexity from JavaScript Remoting – all while integrating with Salesforce1.
CRAIG ISAKSON
Craig Isakson
+ expert systems architect for Salesforce, web and mobile technologies
+ ambitious, fun, sarcastic
+ enjoys incorporating new technologies in innovative ways
+ loves his family and fellow Sundoggers
+ also passionate about running, cycling, photography and near space exploration

Realtime Tracking with the Streaming API
One API. Huge possibilities for innovative user interaction and data notifications. Come discover the top areas of consideration, plus see how to hit the ground running with the streaming API and bonus Google Maps integration via the Salesforce geolocation fields.

Check back soon for session dates, times and registration.

And for conference highlights, blogs and more live from Dreamforce, follow us on social media with #DFWalkABlock.

Posted in Technology | Tagged , , , , , , , | Leave a comment

COUNTDOWN TO #DF14: WALK A BLOCK

Ready for Dreamforce? The #RoadtoDF14 is getting closer, and we’d love for you to “Walk a Block” with us.

At Sundog, we’ve put together a fun, interactive customer journey to Dreamforce 2014.

How’s It Work? 

  1. Your Email Invite – Sign up right here to receive your invitation.
  2. Your Personal Journey – If you join the fun, you’ll receive 10 quick questions via email over the next several weeks.
  3. Free Fitbit & Perks – As our thanks, you’ll get a free Fitbit and other perks when you stop by Sundog’s Basecamp at Dreamforce. We’ll map your personal journey – and show youhow we did it using Salesforce and the ExactTarget Marketing Cloud Platform.
  4. Demos & More – Stop by to say hello or join us for exclusive healthcare demos, manufacturing demos, one-to-one meetings, or even (our personal favorite) a Bloody Mary bar on Thursday before heading back to the airport.

The Pros &  Perks
Whatever your industry may be, you’ll find insightful conversation and hot high-tech solutions. Plus, you’ll get a free Fitbit, cocktails, coffee and everything else you need to recharge. (Oh, and that includes recharging your phone and tablet, too.)

I hope you’ll take the next step! You can also follow us on social media with #DFWalkABlock for conference highlights, blogs and more live from #DF14.

It all comes down to one question: are you in?

Posted in Technology | Tagged , , , , , | Leave a comment

THE IMPORTANCE OF EMPATHY IN YOUR HEALTHCARE MARKETING PLAN

THE IMPORTANCE OF EMPATHY IN YOUR HEALTHCARE MARKETING PLAN

It’s hard to find anyone whose life hasn’t been touched by serious illness in one way or another. We may watch as our grandparents suffer from memory loss, a friend has a baby prematurely, or cancer affects our own health.

Being ill, or watching a loved one who is ill, is without question frightening. Most healthcare workers are well aware of this, and some of the most incredible care givers focus on having empathy towards their patients. Clinics and hospitals are also exploring ways to focus on patient centered care, including employing care guides dedicated to helping patients, and incorporating treatments that focus not only on body, but on mind and soul as well.

For a healthcare organization to express empathy as a whole, however, and make every interaction a patient or family member has as empathetic as it can be is far more difficult. Believe it or not, marketing can play a role in achieving this, and indeed should be framed around ensuring every patient experience is a positive one.

Consider how patients receive communications from your hospital. For example, are the bills you send out nothing but cold statements with a total at the bottom, waiting for payment? Or do you offer information and assistance in that bill? If a person has a question is it clear whom they can contact? Does your hospital offer financial counselors who may be able to talk to patients? Don’t be afraid to empathize with patients over the cost of health care (or any other negative aspect of the system). Patients want to know someone cares, and is there to help them with the realities they face.

Consider also how you manage patients who are managing chronic illness. Frequent interactions with a hospital or clinic can be exhausting for such patients. Most people think of waiting for a doctor or filling out paperwork as a temporary inconvenience. For someone with a chronic illness those inconveniences become major problems. Emerging technologies and programs such as healthcare apps, patient engagement platforms and telemedicine options are working to help these patients live fuller lives while still managing their illnesses.

Finally, don’t discount the role social media can play. If patients are looking for a place to vent (or even just share their story), social media is likely one of the first places they will go. Luckily, mediums like your Facebook page are a perfect location for you to engage in a very personal and human way. Speak to people like they are people, and make sure that you acknowledge what they are saying. Do your best to ensure patients aren’t shuffled off to another automated phone line. Instead, find ways to take on the effort of reaching out to patients, moving complaints and questions quickly through customer service, and keeping a conversation open with patients to make sure their concerns have been resolved.

These are only a few of the ways you can bring more empathy to your health care organization. There are many ways to become patient focused, and many ways to act on patient focused goal to make it clear you practice what you preach, each and every day, in many different ways.

Posted in Technology | Tagged , | Leave a comment

EXCITED TO SPEAK AT DREAMFORCE 2014

Every year there are a few Sundoggers that make their way to San Francisco to attend Salesforce’s annual conference, Dreamforce.  This year will mark my second year attending the conference.  This will also give me another opportunity to share some of my knowledge I have learned on the platform with others by speaking in the Developer Zone.

If you are going to Dreamforce and are looking to learn more about the Streaming API, I’d love for you to attend my session.  There will be loads of real world information that you can use to hit the ground running with this great API.  The session times have not been scheduled as of yet but I will update this post when they do become available.

Session Details:

Realtime Tracking with the Streaming API
A great feature of the Salesforce1 platform is the Streaming API. This API opens up numerous possibilities for innovative user interaction and data notifications. This session will outline a few of the key areas for consideration and demonstrate getting you off the ground and running with the Streaming API with a bonus of Google Maps integration via the Salesforce geolocation fields.

I am looking forward to hitting up all the great sessions and keynotes both in and out of the Developer Zone.  If you are attending and know of any other good sessions I should check out, feel free to leave them in the comments.  As I learn from the sessions I am planning on blogging about what I learn so keep checking back for the highlights!

See you there!

Posted in Technology | Tagged , , , , , , | Leave a comment

CREATING PUBLIC RESTFUL SERVICES IN SALESFORCE

In the course of working with a Salesforce and other connected systems, you are bound to run across a time when you need to create a public web service in Salesforce to be consumed by an outside system.  To me this seems fairly common.  Recently when I was going to try to create such a service, I was having troubles trying to find out where this was documented and was wondering if it was actually possible.

As it turns out, it is possible and pretty easy to setup.  In order to do this you need to create a Site.  To create a Site, log into Salesforce and go to:

Setup – Develop – Sites

and click “New”.  Follow the prompts to finish creating the Site.  After the site is created you can create your web service class.  Simply create a new Apex class and format it similar to the sample outlined here:

1
2
3
4
5
6
7
@RestResource(urlMapping='/yourservicename)
globalclass YourService {
    @HttpGet
    globalstatic String doGet(){
        return 'Hi!!';
    }
}

This class will be the logic for your service and can contain any of the different web service methods.  The magic that makes this public comes from the Site.  If you go back to the Site that you just created and click on the Site and then click on the “Public Access Settings” button, you are brought to the settings page for the public site user.  All you do now is add the recently created web service class to the list of enabled classes.  When the class is added and you click save, the web service is now public!!

You might say, that’s great but how do I hit it?  Here is the naming convention:

https://domainprefix.instance.force.com/sitename/services/apexrest/yourservicename

Replace domainprefix with your domain prefix, instance with your instance, sitename with your site name, and yourservicename with your service name.  That’s all there is to it!

Now that it is created and public, you might want to test it.  My favorite tool for testing these things is DHC.

There you go, pretty simple and powerful.  If you try it out and run into an issue, let me know and I’d be glad to help!!  Happy coding!

Posted in Technology | Tagged , , , | Leave a comment

CALLING RESTFUL SERVICES ON SALESFORCE THROUGH THE NATIVE IOS SDK

Salesforce does a lot of awesome things that help a developer work on getting stuff done rather than setting stuff up.  It is one of the reasons why I like the platform.  A lot of the repetitive work is taken care of automatically.  One such area is by using the Salesforce iOS and Android SDK’s.  They make it a matter of using node.js and running a command in the terminal to get a boilerplate app complete that allows you to connect to Salesforce and start building what needs to get done.

This is awesome but one place where it does lack a bit is in some of the documentation.  It is super easy to perform CRUD operations on any of the objects via the SDK and it is something that is documented extensively.  As you can probably tell from the blog title though, this is how to call RESTful Apex services you created from Salesforce’s Native iOS SDK.

Maybe you are asking why would I need to call webservices?  One answer to that is if you have complex business logic that would be cumbersome to replicate across a number of platforms.  You can gain reusability, lower API calls, and overall speed up your application.

It took some digging but I was able to find others that were trying to do the same thing and that is where I was able to piece together how to perform it.  First, let’s create a simple service that your user has access to:

1
2
3
4
5
6
7
@RestResource(urlMapping='/yourservicename)
globalclass YourService {
    @HttpGet
    globalstatic Account doGet(){
        return [Select Id FROM Account LIMIT 1];
    }
}

Now to call this service from iOS, simply allocate a new SFRestRequest object, set the endpoints to your service, set the method, the path to your service, and send the request while setting the delegate.

1
2
3
4
5
SFRestRequest *request = [[SFRestRequest alloc] init];
request.endpoint = @"/services/apexrest/yourservicename";
request.method = SFRestMethodGET;
request.path = @"/services/apexrest/yourservicename";
[[SFRestAPI sharedInstance] send:request delegate:self];

As you can see this is very similar to the regular CRUD operations and all of the delegate methods are the same as well.  The data sent back will also be the same as the data you get back from the CRUD operations so you can parse through those the same as you normally would in the didLoadResponce method.

One thing to note is that I would recommend the return from your services be Objects or Classes as service mechanism automatically converts those to JSON objects.  If you try to send back a String that is a serialized JSON object, you will have issues on the iOS side (I know this from experience)

Give it a try and let me know if you have any issues.  Happy Coding!!

Posted in Technology | Tagged , , , , , | Leave a comment

IOS JSON TOOLS PART II

If you remember back to the initial blog post on JSON tools for iOS, I had mentioned using Jastor for parsing data in iOS.  Well, Jastor is no longer supported.  However, this does not mean that you have to do it all manually.  There is a new tool on the block and the new tool isJSONModel.

JSONModel picks up where Jastor left off.  It works similar.  Simply build out your data model for the JSON you want to convert to native objects and run some code and presto, your objects are there and ready to use.

Let’s take a look at how this work.  First start by downloading the source from GitHub.  The directory you need is JSONModel.  Import that into your project.  Now you are ready to rock.

Create your model based off of your JSON String extending the JSONModel class.  Then it is as easy as importing JSONModel.h in your class where you want to do the work and running an init method and your object is complete.  Let’s take a look at the example that the provide for the basic use.

JSON:

1
{"id":"10","country":"Germany","dialCode": 49,"isInEurope":true}

Model:

1
2
3
4
5
6
7
8
9
#import "JSONModel.h"
@interface CountryModel : JSONModel
@property (assign, nonatomic)int id;
@property (strong, nonatomic) NSString* country;
@property (strong, nonatomic) NSString* dialCode;
@property (assign, nonatomic)BOOL isInEurope;
@end

Implementation:

1
2
3
4
5
6
#import "CountryModel.h"
...
NSString* json = (fetch here JSON from Internet) ...
NSError* err = nil;
CountryModel* country = [[CountryModel alloc] initWithString:json error:&err];

That is all there is to it.  I have used it a number of times with great success.  Check out the GitHub page to see all of the different things it does as this is just the basic example.

Posted in Technology | Tagged , , , , | Leave a comment