{"id":653,"date":"2017-05-14T17:04:02","date_gmt":"2017-05-14T17:04:02","guid":{"rendered":"http:\/\/bitcows.com\/?p=653"},"modified":"2017-05-14T17:04:02","modified_gmt":"2017-05-14T17:04:02","slug":"access-syncplicity-api-with-appcelerator","status":"publish","type":"post","link":"https:\/\/bitcows.com\/?p=653","title":{"rendered":"Access Syncplicity API with Appcelerator"},"content":{"rendered":"<p><a href=\"https:\/\/www.syncplicity.com\/\">Syncplicity<\/a> is a file share and synchronization service developed by Syncplicity Inc. The service lets users store and synchronize files between computers. It supports Microsoft Windows and macOS. They also have an API that will allow you to manage your folders and files.<\/p>\n<p><strong>API version used in this example was 1.3.11<\/strong><\/p>\n<h2>Before you begin<\/h2>\n<p><strong>Prerequisite<\/strong><br \/>\nBefore you start developing agains most any API you need to sign up for a developer account. Syncplicity is no different. So before you start this you need to make sure you sign up for an account. Use this link follow the instructions to get started with your <a href=\"https:\/\/developer.syncplicity.com\/overview\" target=\"_new\" rel=\"noopener\">Syncplicity account.<\/a><\/p>\n<p><strong>Assumptions<\/strong><\/p>\n<ul>\n<li>Appcelerator account with studio installed<\/li>\n<li>Knowledge of Appcelerator studio or eclipse<\/li>\n<li>Some JavaScript Skills<\/li>\n<li>Some basic API knowledge<\/li>\n<\/ul>\n<p>I&#8217;m not going to go into great depth on how to set up Syncplicity accounts, there is a <a href=\"https:\/\/developer.syncplicity.com\/\" target=\"_new\" rel=\"noopener\">whole site dedicated to that<\/a>.<\/p>\n<p>Once you have your account set up you will need to create an App in the Syncplicity Dev Account. Then you will need 3 main things. <strong>AppKey<\/strong> and <strong>SecretKey<\/strong> from your developer account. The <strong>Authorization Token<\/strong> from your sandbox account.<\/p>\n<ul>\n<li>AppKey<\/li>\n<li>SecretKey<\/li>\n<li>Authorization Token<\/li>\n<\/ul>\n<p><strong style=\"color:red\">From Developer Account<\/strong><br \/>\n<img decoding=\"async\" src=\"http:\/\/bitcows.com\/wp-content\/uploads\/2017\/05\/Screen-Shot-2017-05-14-at-10.22.59-AM.png\" alt=\"\" width=\"800\" \/><br \/>\n<strong style=\"color:red\">From Sandbox<\/strong><br \/>\n<img decoding=\"async\" src=\"http:\/\/bitcows.com\/wp-content\/uploads\/2017\/05\/Screen-Shot-2017-05-14-at-10.27.39-AM.png\" alt=\"\" width=\"800\" \/><\/p>\n<p><a href=\"https:\/\/developer.syncplicity.com\/authentication-using-oauth-20\" target=\"_new\" rel=\"noopener\">For more details on how to do that.<\/a><\/p>\n<p><strong>ONE GOTCHA!<\/strong> This is not really well documented but base on your account and where you are located you might be using the US version or the EU version of the API&#8217;s. Look at your account url if you see the EU in the url then you are using the European version and your endpoints will change. So if you are using the EU version you will need to add .eu to your endpoints like this&#8230;<br \/>\n<code>https:\/\/api.eu.syncplicity.com<\/code><br \/>\notherwise it will be this<br \/>\n<code>https:\/\/api.syncplicity.com<\/code><\/p>\n<p>Once you have your account set up you are ready to start accessing the API&#8217;s<\/p>\n<h2>Lets code<\/h2>\n<p>So first create a new Mobile App Project <strong>File<\/strong> > <strong>New<\/strong> > <strong>Mobile App Project<\/strong><\/p>\n<p>Once you get that created we can create a couple of models. Auth, and Folders.<br \/>\nThe easiest way to create a model is to put yourself in the studio extended perspective.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/bitcows.com\/wp-content\/uploads\/2017\/05\/Screen-Shot-2017-05-14-at-11.12.27-AM.png\" alt=\"\" width=\"400\" \/><\/p>\n<h3>Models<\/h3>\n<p>Then you will be able to create a new model using new. This will stub out a basic model. Choose the sql adapter because it doesn&#8217;t matter we will be changing it.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/bitcows.com\/wp-content\/uploads\/2017\/05\/Screen-Shot-2017-05-14-at-10.54.25-AM.png\" alt=\"\" width=\"400\" \/><\/p>\n<p>After you have created a generic model we will modify it to look like the ones below. We are changing the adapter to restapi (more about that in a min) and adding a URL property, and for thhe Auth model we will delete the extendCollection function.<\/p>\n<p>Add the correct URL&#8217;s in the models. For Auth the URL is<br \/>\n<code>https:\/\/api.eu.syncplicity.com\/oauth\/token<\/code><br \/>\nor<br \/>\n<code>https:\/\/api.syncplicity.com\/oauth\/token<\/code><br \/>\nif you&#8217;re in the US<\/p>\n<p>In our example we have some parameters that we will pass to do this dynamically when we call our fetch. (more about that later).<\/p>\n<h4>Auth.js<\/h4>\n<pre class=\"prettyprint\">exports.definition = {\n\tconfig: {\t\n\t    URL : \"{domain}oauth\/token\",\t    \n\t\tadapter: {\n\t\t\ttype: \"restapi\"\n\t\t}\n\t},\n\textendModel: function(Model) {\n\t\t_.extend(Model.prototype, {});\n\t\treturn Model;\n\t}\n};<\/pre>\n<p>Do the same thing for Folders.<br \/>\nOn Folders leave the extendCollections function<\/p>\n<p>Add the correct URL&#8217;s in the models. For Auth the URL is<br \/>\n<code>https:\/\/api.eu.syncplicity.com\/syncpoint\/syncpoints.svc\/<\/code><br \/>\nor<br \/>\n<code>https:\/\/api.syncplicity.com\/syncpoint\/syncpoints.svc\/<\/code><br \/>\nif you&#8217;re in the US<\/p>\n<h4>Folders.js<\/h4>\n<pre class=\"prettyprint\">exports.definition = {\n    config : {\n        debug : true,\n        URL : \"{domain}syncpoint\/syncpoints.svc\/\",       \n        adapter : {\n            type : 'restapi',\n            collection_name : 'folders',\n            idAttribute : \"id\" \n        }\n    },\n    extendModel : function(Model) {\n        _.extend(Model.prototype, {});\n        return Model;\n    },\n    extendCollection : function(Collection) {\n        _.extend(Collection.prototype, {});\n        return Collection;\n    }\n}; <\/pre>\n<h3>restapi.js<\/h3>\n<p>restapi.js is our adapter that will handle all our API HTTP traffic. Appcelerator uses backbone.js as a way to manage your data and help bind data to our views. The restapi.js file overrides the the Sync function of backbone to make HTTP calls based on what we do on the models and collections. For instance a fetch translates to a GET call of the model we are calling fetch on. <\/p>\n<p>You will need to <a href=\"https:\/\/github.com\/djmason9\/napp.alloy.adapter.restapi\">download that file here<\/a> and add it to your <em>assets<\/em>.<\/p>\n<p><strong>app\/assets\/alloy\/sync\/restapi.js<\/strong><\/p>\n<h3>View<\/h3>\n<p>Let&#8217;s look at the view. We want to set up a Button and a ListView<\/p>\n<pre class=\"prettyprint\">&lt;Alloy&gt;\n    &lt;Collection src=\"folders\"\/&gt;\n    &lt;Window class=\"container\" layout=\"vertical\"&gt;\n        &lt;View id=\"interactionView\" visible=\"false\" layout=\"vertical\"&gt;\n            &lt;Button id=\"label\" onClick=\"getFolders\"&gt;Get Folders&lt;\/Button&gt;\n        &lt;\/View&gt;\n        &lt;ListView defaultItemTemplate=\"template\" id=\"empList\"&gt;\n            &lt;Templates&gt;\n                &lt;ItemTemplate name=\"template\"&gt;\n                    &lt;ImageView bindId=\"img\" class=\"folderIcon\"\/&gt;\n                    &lt;Label bindId=\"name\" class=\"folderName\"\/&gt;\n                &lt;\/ItemTemplate&gt;\n            &lt;\/Templates&gt;\n            &lt;ListSection dataCollection=\"folders\" dataTransform=\"transformFunction\" id=\"foldersList\"&gt;\n                &lt;ListItem img:image=\"\/images\/folder.png\" name:text=\"{Name}\" syncPointId=\"{Id}\" itemId=\"{RootFolderId}\" canEdit=\"true\"\/&gt;\n            &lt;\/ListSection&gt;\n        &lt;\/ListView&gt;\n    &lt;\/Window&gt;\n&lt;\/Alloy&gt;<\/pre>\n<p>The <code>&lt;Collection src=\"folders\"\/&gt;<\/code> Tag will be used to initialize our folder collection so we can bind it to our view. Then in our ListItem we use dataCollection to tell the item to use that Folder collection object. We will bind the Name, Id, and RootFolderId.<\/p>\n<p>The button to get the folders.<br \/>\n<code>&lt;Button id=\"label\" onClick=\"getFolders\"&gt;Get Folders&lt;\/Button&gt;<\/code><\/p>\n<h3>Controller<\/h3>\n<p>The first thing you will need to do in your controller is get the Auth token for our API&#8217;s. I put this in a self calling function <code>(function main(){})();<\/code><br \/>\nFirst create a model <code>var auth = Alloy.createModel(\"auth\");<\/code> then call <strong>fetch<\/strong> which will trigger the Sync function and redirect to the HTTP GET for our first API call.<\/p>\n<p>Lets look at what we are passing. Our data obj<\/p>\n<pre class=\"prettyprint\">var data = {\n    \"grant_type\" : \"client_credentials\"\n};<\/pre>\n<p>is the body of the request. For this call we need to use a POST fetch which is also like a save. But in order to make a fetch a POST we need to set <code>requestMethod : 'POST',<\/code>.<\/p>\n<p>In order to get the domain to our models we do that like this.<\/p>\n<pre class=\"prettyprint\">requestparams : {\n   \"domain\" : domain\n}<\/pre>\n<p>Then we set our headers: Authorization, Sync-App-Token, and Content-Type.<br \/>\nThe Authorization comes from the 64 encoding of a combo of the AppKey and AppSecret <a href=\"https:\/\/developer.eu.syncplicity.com\/authentication-using-oauth-20\" target=\"_new\" rel=\"noopener\">See details<\/a><\/p>\n<p>Lastly a success, and error function. In the success we will set our authorization Bearer Key and the appKey.<\/p>\n<pre class=\"prettyprint\">\/\/get auth token\n    var data = {\n        \"grant_type\" : \"client_credentials\"\n    };\n\n    var auth = Alloy.createModel(\"auth\");\n    auth.fetch({\n        data : data,\n        requestMethod : 'POST',\n        requestparams : {\n            \"domain\" : domain\n        },\n        headers : {\n            \"Authorization\" : \"Basic alFXT0VJzR0doYb0FjNks6ZDRITTdEWFJHU281TEE0UA==\",\n            \"Sync-App-Token\" : \"h8GA1DSjvL2M5gStXj5HmLybcCUjPCjDzDq2O\",\n            \"Content-Type\" : \"application\/x-www-form-urlencoded\"\n        },\n        success : function(model, response, options) {\n            authorization = \"Bearer \" + response.access_token; \/\/global var \n            appKey = response.client_id; \/\/global var\n            \/\/load storage info\n            storageendpoint();\n        },\n        error : function(model, response, options) {\n            console.log(\"fail\");\n        }\n    });<\/pre>\n<p>Now we create a function for getting the folders. Like before we set our domain and headers. Because we created our Collection using the <code>&lt;Collection src=\"folders\"\/&gt;<\/code> we now can access it by <code>Alloy.Collections.folders<\/code> then calling fetch which is delegated to the Sync function in backbone. This does a GET call to our API and populates the collection which in turn binds to our ListView.  <\/p>\n<pre class=\"prettyprint\">function getFolders() {\n    Alloy.Collections.folders.fetch({\n        requestparams : {\n            \"domain\" : domain\n        },\n        headers : {\n            \"Authorization\" : authorization,\n            \"AppKey\" : appKey,\n            \"Accept\" : \"application\/json\",\n            \"Content-Type\" : \"application\/json\"\n        },\n        success : function(model, response, options) {\n          \/\/ do what ever you like here the response is auto magically bound \n          \/\/ to our view, so no need to manually do it here\n        },\n        error : function(model, response, options) {\n            console.log(\"fail\");\n        }\n    });\n}<\/pre>\n<p><a href=\"http:\/\/bitcows.com\/wp-content\/uploads\/2017\/05\/Syncplicity-API-content-guide_1_3_11-1.pdf\">API reference<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Syncplicity is a file share and synchronization service developed by Syncplicity Inc. The service lets users store and synchronize files between computers. It supports Microsoft Windows and macOS. They also have an API that will allow you to manage your folders and files. API version used in this example was 1.3.11 Before you begin Prerequisite&hellip;<\/p>\n<p class=\"more-link\"><a href=\"https:\/\/bitcows.com\/?p=653\" class=\"themebutton\">Read More<\/a><\/p>\n","protected":false},"author":1,"featured_media":655,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,5,9,15,18],"tags":[32],"class_list":["post-653","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-android","category-appcelerator","category-coding","category-ios","category-iphone","tag-appc"],"_links":{"self":[{"href":"https:\/\/bitcows.com\/index.php?rest_route=\/wp\/v2\/posts\/653","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bitcows.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bitcows.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bitcows.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bitcows.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=653"}],"version-history":[{"count":0,"href":"https:\/\/bitcows.com\/index.php?rest_route=\/wp\/v2\/posts\/653\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/bitcows.com\/index.php?rest_route=\/"}],"wp:attachment":[{"href":"https:\/\/bitcows.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=653"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bitcows.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=653"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bitcows.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=653"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}