Android

Upgrading Salesforce SDK App to Android Studio

October 07, 2015

As some of you would have noticed, there is no easy way to integrate the project created/upgraded using "forcedroid" into Android Studio. After some struggle, I followed below steps to acheive this. 

1. Make sure you are on the right Cordova version. As of Salesforce Mobile SDK 3.3, Cordova 3.6.4 is supported. If you have Cordova 4, you have target your platform 
Cordova platform add android@3.6.4
To check the current version use - cordova platform 

2. If you have made earlier attempts, please remove all references to gradle and studio project settings. 
 rm -r .ideafind . -name "*.gradle" -type f -deletefind . -name "*.iml" -type f -delete

3. Also, remove any intermediate builds generated. I cleared the build folder using 

rm -r build

4. Now to make sure all the references correctly placed, open the project in Ecclipse and check if the build is working properly. 

5. Now open import the project into android studio
Open a New Project in the SDK
Once android platform is added to your project, you can open it from within Android Studio:
  1. Launch the Android Studio application.
  2. Select Import Project (Eclipse ADT, Gradle, etc).
  1. Select location where android platform is stored (your/project/platforms/android).
  1. For the Gradle Sync question you can simply answer Yes. Optionally, you may select the destination same as your/project/platforms/android
You are all set now and can build and run the app directly from Android Studio.

6. Now, I faced a series of errors. Resolutions are as stated below. 

Error: Execution failed for task finished with non-zero exit value 2
Resolution: In the main project build.gradle include

defaultConfig {
multiDexEnabled
true
}

Error: package com.google.android.gcm does not exist
Resolution: Include gcm.jar in main project

Error: duplicate entry android studio package debug classes for multidex
Resolution:
Error : Duplicated file copies in APK
ResolutionIn the main project build.gradle include



References:

HTTP

HTTP to HTTPS redirect on IIS

July 17, 2015

The requirement was simple. To redirect all HTTP traffic to HTTPS traffic. First thought that crossed my mind is - "Can't we do it with HTTP redirect?". After trying the approach, the site went into a infinite redirect loop. Pretty obvious! Right? After some googling, this is what I have done. 



<rule name="Redirect to HTTPS" stopProcessing="true">
<match url="(.*)" />
<conditions><add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="SeeOther" />
</rule>











  • Recycle Website
This gave me a great start on URL rewriting. Post this, I setup a proxy and written multiple rewrite rules on IIS. The below article by Jim van de Erve is very helpful. 



Eclipse

Hosting A Static Website In Google App Engine - Eclipse, Java

June 29, 2015

A few months ago, I played around with Google app engine. Somebody asked to set up a personal website which is nothing but a collection of static pages, images and JS widget to do a carousel/gallery. I tried my hand at Google app engine. In another instance, I hosted Google Course Builder on app engine. In both instance, my experience is smooth. Used Google app engine launcher.  Configured .yaml file (Replace application name with the unique application name you set up on google.)What if you want to setup your site using Java on AppEngine. Generally, java developers start with Eclipse. Generally, we follow the tutorial by Google. 
https://cloud.google.com/appengine/docs/java/gettingstarted/introduction

The question is how to put our static files on AppEngine and point index.html as the startup page. Answer - include static file location to app-webengine.xml. 
In this case I created "static" folder under war folder. Also, set the expiration date. Using this setting, server will ask the browser to invalidate the cache for every 30 days and 5 hours. 

<static-files>
        <include path="/static/**" expiration="30d 5h" />
 </static-files>

Next step is to set this folder as the public root. index.html which is configured in web.xml, will be picked up from this folder. 

<public-root>/static</public-root>

Gist: https://gist.github.com/pradeepkumargali/991f02d07c8177028203

The final output can be found at http://sree-kumar.appspot.com. 

References:
http://www.hongkiat.com/blog/host-website-google-server/
http://www.fizerkhan.com/blog/posts/Free-Static-Page-Hosting-on-Google-App-Engine-in-a-5-minutes.html

ADFS

Generate token signing .CER from ADFS Federation Metadata XML

June 24, 2015

While workging on Force.com SSO, our ADFS team has provided me with federation metadata xml only. As per this link, you also need a token-signing certificate from provider to complete the setup and provide the Force.com XML file to ADFS.

Now, the question is how to generate .pem/.cer file out of FederationMetadata.xml file. 


  1. Edit FederationMetadata.xml file, and search for <KeyDescriptor use="signing">. You should find more than one entry. Pick any one of them. 

    2.  Pick the X500Certificate value and save the text as .der file
    3. openssl x509 -in <(base64 --decode FILE_FROM_STEP2.der) -inform DER -out OUTPUT.pem

Use <OUTPUT>.per as Identity Provider Certificate. 

Reference: https://ask.auth0.com/t/how-to-convert-saml-federationmetadata-xml-key-to-pem-or-cer/24

API

Get Complete Package.xml

June 24, 2015

Below are a few interesting post about preparing package.xml automatically.

https://github.com/JitendraZaa/AutoGenerate_Package.xml_Ant
http://www.tquila.com/blog/2014/02/11/salesforce-packagexml-builder
https://packagebuilder.herokuapp.com/

There is no way to figure out wild card metadata components (*) using API. Also, there is no way to figure out what components are not supported as part of force.com migration tool. 

Out of above posts, I found Jitendra's post very interesting and useful. Whereas packagebuilder by Tquila guys, generates an exhaustive list of package.xml file for your organization. 

On a side note Tquila guys have build a few interesting heroku apps. 

https://sfswitch.herokuapp.com/ - To switch components between orgs. 
 - To compare metadata between orgs.

Watch this space for more info!

APEX

Performance tuning of a visualforce page

June 22, 2015

It's my strong belief that a developer should always keep the performance in the top of the priority list. As I was working on a big Visualforce page with lot of aggregations, I wondered how to get best performance out of APEX and VF. 

Both were really helpful, until I ran into following statements. 

Apex Best Practice # 4 states "Use the power of the SOQL where clause to query all data needed in a single query." 

Visualforce guide states

"When writing Apex or SOQL for use with a Visualforce page: 

• Perform calculations in SOQL instead of in Apex, whenever possible.
• Never perform DML inside a loop. 
• Filter in SOQL first, then in Apex, and finally in Visualforce"

Now, I am confused on writing a single SOQL and do the aggregations such as (max,min, sum, avg) in APEX or writing multiple aggregate SOQL's relay the data to VF through APEX. 

I have done a few tests to understand the behaviour, using application performance profiling. 

Note: I used this link to get more insight. But, it's always important to capture right amount of log to troubleshoot the issue. If the log size is bigger than 1MB, some parts may be truncated. This results in incorrect graphs in developer console. Adjust, log levels accordingly to get complete and appropriate log. Also, it's important to leave out first 2-3 logs before you analyze the log as caching plays an important role in reducing turnout times. 

After thorough analysis, VF guide proved right. Ouf of writing multiple aggregate SOQL's  and using Apex collections for aggregation, it's better to choose former approach. The first approach served the request within 50% time of latter. Once cached SOQL's are very quick and Apex processing lags behind (Also don't forget that we have CPU time governor limit to worry about) . Also, It's quick to get the aggregate information from DB to Apex than bring the whole record set for processing. 

Below are few graphs. 


CASE I - Multiple Aggregate SOQL (7ms) 
CASE I - One SOQL - Aggregate using Apex Collections (15ms)

CASE II - Multiple Aggregate SOQL(3ms)

CASE II - One SOQL - Aggregate using Apex Collections (6+ms)





3.0

Mobile SDK Upgrade From 2.3 to 3.0

May 23, 2015

Compilation and Linking Issues

Upgrading Salesforce Mobile SDK from 3.1 to 3.2 is indeed quite simple

$ cd <your_Cordova_app_folder>
$ cordova plugin rm com.salesforce
$ cordova prepare

But every time I did the upgrade from 3.x to latest version of SDK. I see the following set of errors.

Undefined symbols for architecture arm64:
  "_OBJC_CLASS_$_SFHybridViewController", referenced from:
      objc-class-ref in AppDelegate+SalesforceHybridSDK.o
  "_OBJC_CLASS_$_SFDefaultUserManagementViewController", referenced from:
      objc-class-ref in AppDelegate+SalesforceHybridSDK.o
  "_OBJC_CLASS_$_SFUserAccountManager", referenced from:
      objc-class-ref in AppDelegate+SalesforceHybridSDK.o
  "_OBJC_CLASS_$_SFLogger", referenced from:
      objc-class-ref in AppDelegate+SalesforceHybridSDK.o
  "_OBJC_CLASS_$_SalesforceSDKManager", referenced from:
      objc-class-ref in AppDelegate+SalesforceHybridSDK.o
  "_OBJC_CLASS_$_SFLocalhostSubstitutionCache", referenced from:
      objc-class-ref in AppDelegate+SalesforceHybridSDK.o
  "_OBJC_CLASS_$_SFPushNotificationManager", referenced from:
      objc-class-ref in AppDelegate+SalesforceHybridSDK.o
  "_OBJC_CLASS_$_SFHybridViewConfig", referenced from:
      objc-class-ref in AppDelegate+SalesforceHybridSDK.o
ld: symbol(s) not found for architecture arm64

And you see the following binaries (.a) files are missing.


Under "Compile Sources" InitialViewController.m was missing.


Undefined symbols for architecture arm64:
  "_OBJC_CLASS_$_InitialViewController", referenced from:
      objc-class-ref in AppDelegate+SalesforceHybridSDK.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)



Also, please note that there used to be two modules for networking.

libMKNetworkKit-iOS.a
libSalesforceNetworkSDK.a

Now, libSalesforceNetwork.a replace them both.

Resolution

I started off by linking the missed libraries manually.

Link the binaries under "$(SRCROOT)/OneStop/Plugins/com.salesforce"  in Build Phases.  Also, don't forget to add InitialViewController.m under compile sources.
I also added CDVDevice.m to resolve the plugin error.

IT Worked!!

Soon, I faced a roadblock. Once I authorize the app, the screen is stuck at "Loading" view. "Create Passcode" screen never comes up in iOS 8.3 OR intermittently comes up in  older version of iOS 8.

I thought there should be a fix in unstable branch. I downloaded the source code of iOS SDK (https://github.com/forcedotcom/SalesforceMobileSDK-iOS) and generated libraries by running SalesforceSDKCore and SalesforceSDKCommon projects in "Release" mode. In order to run in release mode, I edited the scheme to select "Release" mode for Build Configuration.



Once done, pickup files from "Release-iphoneos" folder. You can navigate to the folder by looking up for the .a file under "Products" folder in Xcode.




I copied all the files to $(SRCROOT)/OneStop/Plugins/com.salesforce and linked them again. This time I made sure names and link order match with the sample apps.

It worked!


If you want to do this in a simple way, just navigate to com.salesforce plugin repo (https://github.com/forcedotcom/SalesforceMobileSDK-CordovaPlugin) and copy the libraries. The task of importance is to make sure you have correct libs and right linking order.

Mac

Sticky horizontal bar on Mac

May 23, 2015

Problem: I encountered a sticky horizontal bar, after a failed or incomplete download. Please see the pic below.
Horizontal Line on Doc
Solution: run killall Dock

References:
http://apple.stackexchange.com/questions/159541/what-is-this-line-on-my-dock 

Access Token

Salesforce OAuth 2.0 "authorize" endpoint doesn't return refresh token

March 04, 2015

Problem:
Salesforce OAuth 2.0 "authorize" (https://login.salesforce.com/services/oauth2/authorize) endpoint doesn't return refresh token

Solution:

The refresh token for the user-agent flow is only issued under one of the following circumstances:

References:

http://salesforce.stackexchange.com/questions/7554/oauth-api-doesnt-send-refresh-token-with-custom-redirect-uri 

https://help.salesforce.com/apex/HTViewHelpDoc?id=remoteaccess_authenticate.htm&language=en_US

Popular Posts

Twitter