<?xml version="1.0" encoding="UTF-8"?><rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
> <channel><title>Marcos Placona Blog</title> <atom:link href="https://www.placona.co.uk/feed/" rel="self" type="application/rss+xml" /><link>https://www.placona.co.uk</link> <description>Programming, technology and the taming of the web.</description> <lastBuildDate>Thu, 08 Feb 2018 11:36:36 +0000</lastBuildDate> <language>en-US</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>https://wordpress.org/?v=4.9.4</generator> <item><title>OSX Pro Tip for .NET Environment Variables</title><link>https://www.placona.co.uk/1592/dotnet/osx-pro-tip-for-environment-variables/</link> <comments>https://www.placona.co.uk/1592/dotnet/osx-pro-tip-for-environment-variables/#comments</comments> <pubDate>Tue, 22 Nov 2016 10:41:43 +0000</pubDate> <dc:creator><![CDATA[Marcos Placona]]></dc:creator> <category><![CDATA[.Net]]></category> <category><![CDATA[.net core]]></category> <category><![CDATA[visual studio for mac]]></category> <guid
isPermaLink="false">https://www.placona.co.uk/?p=1592</guid> <description><![CDATA[Reading time: 2 &#8211; 3 minutes I use environment variables in all my apps to make sure none of my secret keys end up in GitHub. In C#, if you want to get environment variables in your app you just need to use the Environment class and call the method GetEnvironmentVariable() passing the name of the variable [&#8230;]]]></description> <content:encoded><![CDATA[<p>Reading time: 2 &#8211; 3 minutes</p><p><img
class="aligncenter size-full wp-image-1594" src="https://www.placona.co.uk/wp-content/uploads/2016/11/vs-mac-slide.png" alt="vs-mac-slide" width="620" height="347" srcset="https://www.placona.co.uk/wp-content/uploads/2016/11/vs-mac-slide.png 620w, https://www.placona.co.uk/wp-content/uploads/2016/11/vs-mac-slide-300x168.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></p><p>I use <a
href="https://en.wikipedia.org/wiki/Environment_variable">environment variables</a> in all my apps to make sure none of my secret keys end up in GitHub. In C#, if you want to get environment variables in your app you just need to use the <a
href="https://msdn.microsoft.com/en-us/library/system.environment(v=vs.110).aspx">Environment class</a> and call the method <code>GetEnvironmentVariable()</code> passing the name of the variable you&#8217;ve already defined.</p><pre class="crayon-plain-tag">accountSid = Environment.GetEnvironmentVariable("TWILIO_ACCOUNT_SID");</pre><p>I have recently switched from building and running apps directly on the terminal and Visual Studio Code to using <a
href="https://www.visualstudio.com/vs/visual-studio-mac/">Visual Studio for Mac</a>. I opened up an application I had already built and knew worked and tried it out. I started to get some weird errors where it would claim to not find my environment variables.</p><p>I went ahead and run my application from terminal and it worked as expected.</p><p>A bit of Googling and I landed on this StackOverflow <a
href="http://stackoverflow.com/questions/35643759/c-sharp-environment-getenvironmentvariable-not-working-on-osx/35644532">thread</a>. But here&#8217;s the gist of it:</p><blockquote><p>OS-X GUI apps will not inherit your private/custom env vars that are defined via a shell (bash, zsh, etc&#8230;) if they are launched from Finder/Spotlight</p></blockquote><p>The solution to that is to instead of starting Visual Studio for Mac from finder, you can start it from terminal and it will then inherit your environment variables. You can start it like this:</p><pre class="crayon-plain-tag">/Applications/Visual\ Studio.app/Contents/MacOS/VisualStudio &amp;</pre><p>But remembering that will be hard, and you will end up tabbing through your terminal until you get to it every single time. So here&#8217;s an alias:</p><pre class="crayon-plain-tag">alias vs='/Applications/Visual\ Studio.app/Contents/MacOS/VisualStudio &amp;'</pre><p>If you run that on your terminal, you can then just run <code>vs</code> afterwards, and Visual Studio for Mac will start inheriting your environment variables.</p><p>This will disappear every time you restart your terminal though, so add it to your <code>.bash_profile</code> or equivalent if you wanna make it permanent.</p> ]]></content:encoded> <wfw:commentRss>https://www.placona.co.uk/1592/dotnet/osx-pro-tip-for-environment-variables/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Building a beautifully smart form in Android using RxJava</title><link>https://www.placona.co.uk/1574/android/building-a-beautifully-smart-form-in-android-using-rxjava/</link> <comments>https://www.placona.co.uk/1574/android/building-a-beautifully-smart-form-in-android-using-rxjava/#respond</comments> <pubDate>Sun, 13 Nov 2016 10:05:59 +0000</pubDate> <dc:creator><![CDATA[Marcos Placona]]></dc:creator> <category><![CDATA[Android]]></category> <guid
isPermaLink="false">https://www.placona.co.uk/?p=1574</guid> <description><![CDATA[Reading time: 5 &#8211; 8 minutes I don&#8217;t think I know a single Android developer who&#8217;s not stoked about Reactive Programming with RxAndroid right now. I totally dig the idea of subscribing to events emitted by my applications and be able to react accordingly. With Rx you have Observables and Observers. Observables are expected to emit values. While Observers [&#8230;]]]></description> <content:encoded><![CDATA[<p>Reading time: 5 &#8211; 8 minutes</p><p>I don&#8217;t think I know a single Android developer who&#8217;s not stoked about <a
href="http://reactivex.io/">Reactive Programming</a> with <a
href="https://github.com/ReactiveX/RxAndroid">RxAndroid</a> right now. I totally dig the idea of subscribing to events emitted by my applications and be able to react accordingly.</p><p>With Rx you have <a
href="http://reactivex.io/documentation/observable.html">Observables</a> and <a
href="http://reactivex.io/RxJava/javadoc/rx/Observer.html">Observers</a>. <code>Observables</code> are expected to <code>emit</code> values. While <code>Observers</code> watch <code>Observables</code> by <code>subscribing</code> to them.</p><p>Observing a button for example would look like this:</p><pre class="crayon-plain-tag">Subscription buttonSub = RxView.clicks(mLoginButton).subscribe(aVoid -&gt; {
  //handle on click here
});</pre><p>But let&#8217;s look at a more real-life example.</p><h3>Requirements</h3><p>I would like to have a reactive login form that updates itself according to the values entered. Such that:</p><p><img
class="wp-image-1581 alignright" style="padding-right: 10px;" src="https://www.placona.co.uk/wp-content/uploads/2016/11/AndroidRx-1.gif" alt="androidrx" width="146" height="299" /></p><ul><li>It only shows a login button once the username and password have been validated</li><li>It lets me know that values I entered for each field are correct so I can start working on the next field.</li></ul><h3></h3><h3></h3><h3></h3><h3></h3><h3>Our tools</h3><ul><li>I&#8217;ll be using <a
href="https://developer.android.com/studio/index.html">Android Studio</a> here, but you should feel free to use whatever floats your boat.</li><li>The libraries <a
href="http://jakewharton.github.io/butterknife/">ButterKnife </a>,  <a
href="https://github.com/JakeWharton/RxBinding">RxBinding</a> &amp; <a
href="https://github.com/evant/gradle-retrolambda">RetroLambda</a>. You can see the versions I used <a
href="https://github.com/mplacona/RXLogin/blob/master/app/build.gradle">here</a>.</li></ul><h3>The form</h3><p>You can download the entire project from <a
href="https://github.com/mplacona/RXLogin">my GitHub repo</a>, or follow this tutorial.</p><p>Start by creating a new project with an <code>Empty Activity</code>, and once that&#8217;s completed open <em>activity_main.xml</em>.</p><p>I used the <a
href="http://android-developers.blogspot.co.uk/2015/05/android-design-support-library.html">Design Support Library</a> to create my form.</p><pre class="crayon-plain-tag">&lt;ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:fitsSystemWindows="true"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity"
    android:background="@color/colorPrimary"&gt;
    &lt;LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="56dp"
        android:paddingLeft="24dp"
        android:paddingRight="24dp"&gt;
        &lt;ImageView android:src="@drawable/selfie"
            android:layout_width="wrap_content"
            android:layout_height="72dp"
            android:layout_marginBottom="24dp"
            android:layout_gravity="center_horizontal" /&gt;
            &lt;!-- Login Label --&gt;
            &lt;android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:layout_marginBottom="8dp"&gt;
                &lt;EditText android:id="@+id/login_et"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="Email" /&gt;
            &lt;/android.support.design.widget.TextInputLayout&gt;
            &lt;!-- Password Label --&gt;
            &lt;android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:layout_marginBottom="8dp"&gt;
                &lt;EditText android:id="@+id/password_et"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:inputType="text|textVisiblePassword"
                    android:hint="Password"/&gt;
            &lt;/android.support.design.widget.TextInputLayout&gt;
            &lt;android.support.v7.widget.AppCompatButton
                android:id="@+id/login_bt"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="24dp"
                android:layout_marginBottom="24dp"
                android:padding="12dp"
                android:text="Login"/&gt;
        &lt;/LinearLayout&gt;
&lt;/ScrollView&gt;</pre><p>Once that form is created, we will add some references to it at the top of our MainActivity class.</p><pre class="crayon-plain-tag">public class MainActivity extends AppCompatActivity {
    @BindView(R.id.login_et)
    EditText mLogin;
    @BindView(R.id.password_et)
    EditText mPassword;
    @BindView(R.id.login_bt)
    Button mLoginButton;
    @BindDrawable(android.R.drawable.presence_busy)
    Drawable mInvalidField;
    @BindDrawable(android.R.drawable.presence_online)
    Drawable mValidField;</pre><p>We&#8217;re using ButterKnife here to bind the widgets to our layout. Inside the <code>onCreate</code> method we need to make sure to initialise ButterKnife.</p><pre class="crayon-plain-tag">protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);</pre><p><img
class="size-full wp-image-1585 alignleft" src="https://www.placona.co.uk/wp-content/uploads/2016/11/rxAndroid1.1.png" alt="rxandroid1-1" width="139" height="280" />Give that a spin and you should see our form, and really nothing else.</p><p>But now we know our form is working and all the fields are displaying and bound correctly. You will notice that if you try to do anything with this form though, no validation kicks in.</p><p>Also, the login button is displaying, and one of our initial requirements was that the login button only displays once we have validated that the data entered in the form is in the format we expect.</p><p>We will add this functionality now by adding three new <code>Observables</code> to our class and subscribing to them to check for when values change and become valid.</p><h3>Validation</h3><p>I want to validate that the username is in fact an email address. The easiest way we can do this is by using a regular expression. The <a
href="http://emailregex.com/">EmailRegex</a> website has a good one we can use here. So we will just copy that and create a new method called <code>isValidLogin</code> that returns a boolean to indicate whether the email is valid or not.</p><pre class="crayon-plain-tag">private boolean isValidLogin(CharSequence value) {
    return value.toString().matches("(?:[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])");
}</pre><p>You could change that to fit anything you need. In my first go at this I was only checking whether the <code>value</code> had 5 characters or more.</p><p>Next we will create similar method to check whether the password is valid according to our requirements. I kept this simple and only checked that the password is anything between 4 and 8 characters and that it has at least one number.</p><pre class="crayon-plain-tag">private boolean isValidPassword(CharSequence value) {
    return value.toString().matches("^(?=.*\\d).{4,8}$");
}</pre><p>Again, feel free to modify this to do whatever you want it to do. There are regular expression recipes all over the internet so just search for something that works for you.</p><h3>Putting it all together</h3><p>We need to start using these validation methods with our code, so go ahead and create three new <code>Observables</code> in the <code>onCreate</code> method.</p><pre class="crayon-plain-tag">ButterKnife.bind(this);
Observable&lt;CharSequence&gt; loginObservable = RxTextView.textChanges(mLogin);
Observable&lt;CharSequence&gt; passwordObservable = RxTextView.textChanges(mPassword);
Observable&lt;Boolean&gt; combinedObservables = Observable.combineLatest(loginObservable, passwordObservable, (o1, o2) -&gt; isValidLogin(o1) &amp;&amp; isValidPassword(o2));</pre><p>The first and the second one are really simple and use the RxBinding library to check for text changes on the form field. The third one is the most interesting in my option, as it <a
href="http://reactivex.io/documentation/operators/combinelatest.html">combines the latest vales</a> emitted by each one of the previous <code>Observables</code> and then checks to see whether their values are considered to be valid according to our validation rules.</p><p>But we&#8217;re just emitting values here, and don&#8217;t really have anything watching for these value changes and reacting to it.</p><p>We will change our code to add subscribers (<code>Observers</code>) to each one of our <code>Observables</code>.</p><pre class="crayon-plain-tag">ButterKnife.bind(this);
Observable&lt;CharSequence&gt; loginObservable = RxTextView.textChanges(mLogin);
loginObservable
        .map(this::isValidLogin)
        .subscribe(isValid -&gt; mLogin.setCompoundDrawablesRelativeWithIntrinsicBounds(null,null, (isValid ? mValidField : mInvalidField), null));
Observable&lt;CharSequence&gt; passwordObservable = RxTextView.textChanges(mPassword);
passwordObservable
        .map(this::isValidPassword)
        .subscribe(isValid -&gt; mPassword.setCompoundDrawablesRelativeWithIntrinsicBounds(null,null, (isValid ? mValidField : mInvalidField), null));
Observable&lt;Boolean&gt; combinedObservables = Observable.combineLatest(loginObservable, passwordObservable, (o1, o2) -&gt; isValidLogin(o1) &amp;&amp; isValidPassword(o2));
combinedObservables.subscribe(isVisible -&gt; mLoginButton.setVisibility(isVisible ? View.VISIBLE : View.GONE));</pre><p>The first and second <code>Observers</code> are similar and will change the drawable in the field to a green dot when the values entered are valid.</p><p>The third <code>Observer</code>  will change the button to visible once the values are correct, and hide it if the values become incorrect again.</p><h3>React to all the things</h3><p>Reactive programming is a lot of fun, and once you get started with it you will want to find an excuse to subscribe to every one of your data streams. Bet you think our little form works way better now than before.</p><p>Donn Felker wrote a really good Rx tutorial <a
href="https://realm.io/news/donn-felker-reactive-android-ui-programming-with-rxbinding/">here</a> that goes through a lot of the basics when getting started with RxAndroid. The <a
href="http://reactivex.io/documentation/operators.html">Operators page</a> in the Reactive.io website is also a great resource to help you understanding what all the operators do.</p><p>Have fun!</p> ]]></content:encoded> <wfw:commentRss>https://www.placona.co.uk/1574/android/building-a-beautifully-smart-form-in-android-using-rxjava/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Picasso &#8211; Same URL but different content</title><link>https://www.placona.co.uk/1547/android/picasso-same-url-but-different-content/</link> <comments>https://www.placona.co.uk/1547/android/picasso-same-url-but-different-content/#comments</comments> <pubDate>Sat, 17 Sep 2016 22:26:34 +0000</pubDate> <dc:creator><![CDATA[Marcos Placona]]></dc:creator> <category><![CDATA[Android]]></category> <category><![CDATA[android]]></category> <category><![CDATA[caching]]></category> <category><![CDATA[http request hack]]></category> <category><![CDATA[picasso]]></category> <guid
isPermaLink="false">https://www.placona.co.uk/?p=1547</guid> <description><![CDATA[Reading time: 3 &#8211; 5 minutes I love using Square&#8217;s Picasso library whenever I need to load images into my Android applications. It lets me load images from the internet into ImageViews with a single line of code. [crayon-5a7db1bf83973749097656/] Doing the same thing without the library is a whole different story, and Picasso even takes care of [&#8230;]]]></description> <content:encoded><![CDATA[<p>Reading time: 3 &#8211; 5 minutes</p><p>I love using Square&#8217;s <a
href="http://square.github.io/picasso/">Picasso</a> library whenever I need to load images into my Android applications. It lets me load images from the internet into ImageViews with a single line of code.</p><pre class="crayon-plain-tag">Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);</pre><p>Doing the same thing without the library is a whole different story, and Picasso even takes care of <a
href="http://square.github.io/picasso/#features">caching and transformations</a> for me.</p><h3>Until I hit a snag</h3><p>Today I was working on a <a
href="https://medium.com/@mplacona/exploring-the-vastness-of-realm-a-cross-platform-mobile-database-cda48ad76616">demo</a> with a <a
href="https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html">RecyclerView</a> that loads random images from the internet to display as icons for each one of the items. The naive implementation on my View Adapter looked like this:</p><pre class="crayon-plain-tag">private static final String ICON_URL = "https://unsplash.it/50/50?random";
...
@Override
public void onBindRealmViewHolder(ViewHolder viewHolder, int position) {
    final Note note = realmResults.get(position);
    viewHolder.mText.setText(note.getText());
    viewHolder.mDate.setText(note.getDate().toString());
    Picasso.with(getApplicationContext())
            .load(ICON_URL)
            .placeholder(R.mipmap.ic_launcher)
            .error(R.mipmap.error)
            .into(viewHolder.mIcon);
}</pre><p>I&#8217;ve highlighted the code above to get you to think about what is going to happen with the result on the RecyclerView. Make sure you open the <a
href="https://unsplash.it/50/50?random">ICON_URL</a> on a new tab and refresh a few times to help you out.</p><p><img
class="alignnone size-full" src="https://media2.giphy.com/media/5gjGk5uuhRuVi/giphy.gif" alt="thinking..." width="500" height="213" /></p><p>If your guess was that all the images would be loaded the same for every single item on the RecyclerView, then you&#8217;ve either come across this problem or are pretty good at guessing.</p><p>Enabling logs show distinct requests being created from Picasso to the URL, which should in theory result in different images right?</p><pre class="crayon-plain-tag">6978-6978/uk.co.placona.realmnotes D/Picasso: Main        created      [R4] Request{https://unsplash.it/50/50?random}
6978-6978/uk.co.placona.realmnotes D/Picasso: Main        created      [R5] Request{https://unsplash.it/50/50?random}
6978-6978/uk.co.placona.realmnotes D/Picasso: Main        created      [R6] Request{https://unsplash.it/50/50?random}
6978-6978/uk.co.placona.realmnotes D/Picasso: Main        created      [R7] Request{https://unsplash.it/50/50?random}</pre><p>As it turns out, it seems like the default behaviour for when you try to load the same URL with Picasso is that it only ever queues your request once. A deeper look into the log showed me only one of the requests was enqueued and executed. And this was not the easiest thing to realise in all honesty.</p><pre class="crayon-plain-tag">6978-6978/uk.co.placona.realmnotes D/Picasso: Main        created      [R29] Request{https://unsplash.it/50/50?random}
6978-13784/uk.co.placona.realmnotes D/Picasso: Dispatcher  enqueued     [R29]+5ms
6978-13787/uk.co.placona.realmnotes D/Picasso: Hunter      executing    [R29]+7ms
6978-6978/uk.co.placona.realmnotes D/Picasso: Main        created      [R30] Request{https://unsplash.it/50/50?random}
6978-13784/uk.co.placona.realmnotes D/Picasso: Hunter      joined       [R30]+0ms to [R29]+14ms, [R30]+0ms
6978-6978/uk.co.placona.realmnotes D/Picasso: Main        created      [R31] Request{https://unsplash.it/50/50?random}
6978-13784/uk.co.placona.realmnotes D/Picasso: Hunter      joined       [R31]+0ms to [R29]+22ms, [R30]+9ms, [R31]+0ms
6978-6978/uk.co.placona.realmnotes D/Picasso: Main        created      [R32] Request{https://unsplash.it/50/50?random}
6978-13784/uk.co.placona.realmnotes D/Picasso: Hunter      joined       [R32]+3ms to [R29]+43ms, [R30]+30ms, [R31]+21ms, [R32]+11ms</pre><p>Theoretically loading up the same page over and over again should always result on the same content and if you remember well, in the beginning of this post I mentioned Picasso takes care of caching for me, and I presume in this case the URL will be the key.</p><p>Let&#8217;s make a small change to the code and check whether we can force Picasso to think that it needs to enqueue and execute every single one of our URLs regardless.</p><pre class="crayon-plain-tag">Picasso.with(getApplicationContext())
                    .load(ICON_URL + "&amp;" + position)
                    .placeholder(R.mipmap.ic_launcher)
                    .error(R.mipmap.error)
                    .into(viewHolder.mIcon);</pre><p>Doing pretty much the same thing as before, but notice I now have a number that gets appended to each URL. This should make my URLs look like this: https://unsplash.it/50/50?random&amp;{number}.</p><p><img
class="alignnone" src="http://media0.giphy.com/media/qdBHt01vnl972/giphy.gif" alt="I'm ugly and I'm proud" width="500" height="375" /></p><p>Now let&#8217;s look at the logs:</p><pre class="crayon-plain-tag">6978-6978/uk.co.placona.realmnotes D/Picasso: Main        created      [R43] Request{https://unsplash.it/50/50?random&amp;0}
6978-1213/uk.co.placona.realmnotes D/Picasso: Dispatcher  enqueued     [R43]+1ms
6978-6978/uk.co.placona.realmnotes D/Picasso: Main        created      [R44] Request{https://unsplash.it/50/50?random&amp;1}
6978-1225/uk.co.placona.realmnotes D/Picasso: Hunter      executing    [R43]+35ms
6978-1213/uk.co.placona.realmnotes D/Picasso: Dispatcher  enqueued     [R44]+22ms
6978-1230/uk.co.placona.realmnotes D/Picasso: Hunter      executing    [R44]+37ms
6978-6978/uk.co.placona.realmnotes D/Picasso: Main        created      [R45] Request{https://unsplash.it/50/50?random&amp;2}
6978-1213/uk.co.placona.realmnotes D/Picasso: Dispatcher  enqueued     [R45]+0ms
6978-1252/uk.co.placona.realmnotes D/Picasso: Hunter      executing    [R45]+2ms
6978-6978/uk.co.placona.realmnotes D/Picasso: Main        created      [R46] Request{https://unsplash.it/50/50?random&amp;3}
6978-1213/uk.co.placona.realmnotes D/Picasso: Dispatcher  enqueued     [R46]+1ms
6978-1225/uk.co.placona.realmnotes D/Picasso: Hunter      decoded      [R43]+669ms
6978-1225/uk.co.placona.realmnotes D/Picasso: Hunter      executing    [R46]+477ms</pre><p>Each one of my URLs now started a request that was <em>created</em>, <em>enqueued</em> and <em>executed</em>. And sure enough, now each one of the items on my RecyclerView has a different image for its icon.</p><h3>But there is a better way. Right?</h3><p>I found a few threads like <a
href="https://github.com/square/picasso/issues/438">this one</a> indicating that a combination of the <a
href="https://square.github.io/picasso/2.x/picasso/com/squareup/picasso/Picasso.html#invalidate-java.lang.String-">invalidate()</a> method,  <a
href="https://square.github.io/picasso/2.x/picasso/com/squareup/picasso/MemoryPolicy.html">MemoryPolicy</a> and <a
href="https://square.github.io/picasso/2.x/picasso/com/squareup/picasso/NetworkPolicy.html">NetworkPolicy</a> should get this to work. So something like this should do the trick right?</p><pre class="crayon-plain-tag">Picasso.with(mContext).invalidate(file);
Picasso.with(mContext)
                    .load(ICON_URL)
                    .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
                    .networkPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE)
                    .placeholder(R.mipmap.ic_launcher)
                    .error(R.mipmap.error)
                    .into(viewHolder.mIcon);</pre><p>Nope! Doing so presented the same behaviour as before, where only one item is ever enqueued.</p><p>So for the time being, I will stick to the solution where I add a query parameter to each one of the images to make sure I always get random results on the same URL.</p><h3>Know the solution?</h3><p>I would love to hear from you what the correct/less hacky solution you found to this problem. Drop a comment bellow if you know how to make this work without having to fiddle with the URL.</p> ]]></content:encoded> <wfw:commentRss>https://www.placona.co.uk/1547/android/picasso-same-url-but-different-content/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>How to secure Apache with Let&#8217;s Encrypt and CloudFlare on Centos</title><link>https://www.placona.co.uk/1535/general-techie-stuff/how-to-secure-apache-with-lets-encrypt-and-cloudflare-on-centos/</link> <comments>https://www.placona.co.uk/1535/general-techie-stuff/how-to-secure-apache-with-lets-encrypt-and-cloudflare-on-centos/#comments</comments> <pubDate>Mon, 28 Mar 2016 16:16:36 +0000</pubDate> <dc:creator><![CDATA[Marcos Placona]]></dc:creator> <category><![CDATA[General Techie Stuff]]></category> <category><![CDATA[Technology]]></category> <category><![CDATA[VPS]]></category> <category><![CDATA[Website Optimization]]></category> <category><![CDATA[centos]]></category> <category><![CDATA[cloudflare]]></category> <category><![CDATA[Failed authorization procedure]]></category> <category><![CDATA[letsencrypt]]></category> <category><![CDATA[security]]></category> <category><![CDATA[ssl]]></category> <category><![CDATA[tls]]></category> <category><![CDATA[wordpress]]></category> <guid
isPermaLink="false">https://www.placona.co.uk/?p=1535</guid> <description><![CDATA[Reading time: 4 &#8211; 7 minutes I took it upon myself to converting a couple of my domains to use Let&#8217;s Encrypt in order to offer a secure connection to them. If you haven&#8217;t heard about Let&#8217;s Encrypt by now you&#8217; have probably been living under a rock. If that&#8217;s the case though, have a read [&#8230;]]]></description> <content:encoded><![CDATA[<p>Reading time: 4 &#8211; 7 minutes</p><p>I took it upon myself to converting a couple of my domains to use <a
href="https://letsencrypt.org/">Let&#8217;s Encrypt</a> in order to offer a secure connection to them. If you haven&#8217;t heard about Let&#8217;s Encrypt by now you&#8217; have probably been living under a rock. If that&#8217;s the case though, have a read at <a
href="https://letsencrypt.org/how-it-works/">this page</a> and you&#8217;ll get up to speed with it.</p><p>Their <a
href="https://letsencrypt.org/getting-started/">getting started page</a> describes the entire process of installation, but that didn&#8217;t really resonate with me. Upon some googling I found a great <a
href="https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-centos-7">Digital Ocean article</a> which made a lot more sense to me. That is an absolutely fine tutorial if you&#8217;re not using <a
href="https://www.cloudflare.com">CloudFlare</a>. If you came to this article from a Google search though, chances are you&#8217;re also using CloudFlare and are having issues like some of the following:</p><ul><li><em>Failed authorization procedure</em></li><li><em>The following &#8216;urn:acme:error:unauthorized&#8217; errors were reported by the server</em></li><li><em>urn:acme:error:unauthorized :: The client lacks sufficient authorization ::</em></li></ul><p>Hopefully this article will show you how to get that nice green padlock showing on your website. Props to the <a
href="https://support.cloudflare.com/hc/en-us/articles/214820528-How-to-Validate-a-Let-s-Encrypt-Certificate-on-a-Site-Already-Active-on-CloudFlare">article on Cloudflare&#8217;s support page</a> that took me halfway the process.</p><h3>Install the dependencies</h3><p>I usually SSH to my server to get these things done, but this step may vary if you access your server differently.</p><p>On your terminal start by installing EPEL (Extra Packages for Enterprise Linux) repository:</p><pre class="crayon-plain-tag">sudo yum install epel-release</pre><p>Then install GIT. We will use it to get the latest version of the Let&#8217;s Encrypt Client.</p><pre class="crayon-plain-tag">sudo yum install git</pre><p></p><h3>Download and install Let&#8217;s Encrypt Client</h3><p>Start off by cloning the repository and then saving it to <em>/opt/letsencrypt</em>. Feel free to save it elsewhere but <em>/opt</em> is a good location for third party packages.</p><pre class="crayon-plain-tag">sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt</pre><p></p><h3>Generate a new SSL certificate</h3><p></p><pre class="crayon-plain-tag">cd /opt/letsencrypt</pre><p>This is where we go differently from the Digital Ocean article as we will generate our SSL certificate using the webroot option.</p><pre class="crayon-plain-tag">sudo /root/.local/share/letsencrypt/bin/letsencrypt certonly --webroot --webroot-path /var/www/placona.co.uk --renew-by-default --email my_email.com --text --agree-tos -d placona.co.uk -d www.placona.co.uk</pre><p>We&#8217;ve used the following flags for this setup.</p><ul><li><strong>&#8211;webroot-path</strong> is the directory on your server where your site is located. This is not your webserver&#8217;s root directory but your website&#8217;s</li><li><strong>&#8211;renew-by-default</strong> selects renewal by default when domains are a superset of a previously attained cert</li><li><strong>&#8211;email</strong> is the email used for registration and recovery contact.</li><li><strong>&#8211;text</strong> displays text output</li><li><strong>&#8211;agree-tos</strong> agrees to Let’s Encrypt’s Subscriber Agreement</li><li><strong>-d</strong> specifies hostnames to add to the SAN. You can specify as many domains and subdomains as you need here as shown above</li></ul><p>After you run that you should get a message saying your certificate chain has been saved.</p><div
id="attachment_1537" style="max-width: 697px" class="wp-caption aligncenter"><img
class="wp-image-1537 size-full" src="https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt.png" alt="letsencrypt" width="687" height="354" srcset="https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt.png 687w, https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt-300x155.png 300w, https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt-676x348.png 676w" sizes="(max-width: 687px) 100vw, 687px" /><p
class="wp-caption-text">Apparently I also need to read about upgrading Python on Centos without breaking everything</p></div><h3>Setting up the SSL certificate with Apache</h3><p>With your certificate created it&#8217;s time to tell Apache that you want it to use that. On terminal run:</p><pre class="crayon-plain-tag">sudo ./letsencrypt-auto --apache -d placona.co.uk -d www.placona.co.uk</pre><p>And you should get a screen that looks like this:</p><p><img
class="aligncenter size-full wp-image-1538" src="https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt2.png" alt="letsencrypt2" width="574" height="293" srcset="https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt2.png 574w, https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt2-300x153.png 300w" sizes="(max-width: 574px) 100vw, 574px" /></p><p>Apache still doesn&#8217;t know about this new certificate but we&#8217;re about to change that by selecting option 1 and on the subsequent screen choosing whether we want to make HTTP required or optional. I chose <em>Secure</em> here as I want all of my requests to be redirected to HTTPS.</p><p>You should then end up with a confirmation screen that tells you to check that your certificates are correctly installed. This procedure will have modified your httpd.conf file to add redirects so all requests that are non HTTPS are now redirected to be HTTPS.</p><p><img
class="aligncenter size-full wp-image-1539" src="https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt3.png" alt="letsencrypt3" width="665" height="269" srcset="https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt3.png 665w, https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt3-300x121.png 300w" sizes="(max-width: 665px) 100vw, 665px" /></p><p>Go ahead and hit those URL&#8217;s and you should see that they both get a grade A pass.</p><p><img
class="aligncenter size-full wp-image-1540" src="https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt4.png" alt="letsencrypt4" width="1097" height="514" srcset="https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt4.png 1097w, https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt4-300x141.png 300w, https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt4-768x360.png 768w, https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt4-1024x480.png 1024w, https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt4-676x317.png 676w" sizes="(max-width: 1097px) 100vw, 1097px" /></p><h3>Updating Cloudflare</h3><p>We need to tell CloudFlare that we now have an SSL certificate and want the communication to our website to use it. On CloudFlare&#8217;s dashboard for your chosen website choose <em>Crypto</em> and under <em>SSL</em> choose <em>Full (Strict)</em>. You will probably want to use <em>Flexible</em> here if during the previous step you chose HTTPS to be optional.</p><p><img
class="aligncenter size-full wp-image-1541" src="https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt5.png" alt="letsencrypt5" width="973" height="495" srcset="https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt5.png 973w, https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt5-300x153.png 300w, https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt5-768x391.png 768w, https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt5-676x344.png 676w" sizes="(max-width: 973px) 100vw, 973px" /></p><p>At this point you should be done and your website should be showing a nice green padlock on the URL bar.</p><h3>Unless&#8230;</h3><p>You&#8217;re using WordPress. In this case you will also want to update it so the URL is always HTTPS. You can do that by going into WordPress Admin, and then navigating to Settings &gt; General.</p><p><img
class="aligncenter size-full wp-image-1542" src="https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt6.png" alt="letsencrypt6" width="957" height="327" srcset="https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt6.png 957w, https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt6-300x103.png 300w, https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt6-768x262.png 768w, https://www.placona.co.uk/wp-content/uploads/2016/03/letsencrypt6-676x231.png 676w" sizes="(max-width: 957px) 100vw, 957px" /></p><p>And that will make sure every image and every URL on your WordPress site is served via HTTPS.</p> ]]></content:encoded> <wfw:commentRss>https://www.placona.co.uk/1535/general-techie-stuff/how-to-secure-apache-with-lets-encrypt-and-cloudflare-on-centos/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Multi-Line C# Strings</title><link>https://www.placona.co.uk/1524/dotnet/multi-line-c-sharp-strings/</link> <comments>https://www.placona.co.uk/1524/dotnet/multi-line-c-sharp-strings/#comments</comments> <pubDate>Mon, 22 Feb 2016 11:28:01 +0000</pubDate> <dc:creator><![CDATA[Marcos Placona]]></dc:creator> <category><![CDATA[.Net]]></category> <category><![CDATA[.net]]></category> <category><![CDATA[c#]]></category> <guid
isPermaLink="false">http://www.placona.co.uk/?p=1524</guid> <description><![CDATA[Reading time: 2 &#8211; 3 minutes I’ve seen this question being asked on StackOverflow so many times I event thought about writing a bot to automatically reply to it. The answers vary slightly according to the experience of each developer but the question is always the same. How do you create multi-line C# strings? Assigning [&#8230;]]]></description> <content:encoded><![CDATA[<p>Reading time: 2 &#8211; 3 minutes</p><p>I’ve seen this question being asked on StackOverflow so many times I event thought about writing a bot to automatically reply to it.</p><p>The answers vary slightly according to the experience of each developer but the question is always the same. How do you create multi-line C# strings?</p><h2>Assigning multi-line strings to a variable</h2><p>Say you’re trying to assign an XML string to a variable and want your code to still look presentable. The correct way to do that would be as follows:</p><pre class="crayon-plain-tag">string twiml = @"
&lt;Response&gt;
    &lt;Dial&gt;
        &lt;Number&gt;+441234567890&lt;/Number&gt;
    &lt;/Dial&gt;
&lt;/Response&gt;
";</pre><p>Notice all I had to do was add an <strong><i>@</i></strong> before the speechmarks, and this gives multi-line capabilities to my string.</p><p>But what if I wanted to have dynamic values inside my string? Say values coming from variables for example.</p><h2>Assigning dynamic multi-line strings to a variable</h2><p>What most people will do here is make the assumption you can use concatenation to inject variables in by doing something like this.</p><pre class="crayon-plain-tag">string twiml = @"
&lt;Response&gt;
    &lt;Dial&gt;
        &lt;Number&gt;" + To + @"&lt;/Number&gt;
    &lt;/Dial&gt;
&lt;/Response&gt;</pre><p>That is a horrible way of doing this though. Every time you add a new variable, you need to use an <strong>@</strong> again to tell the compiler you’re starting a new multi-line string.</p><p>To assign dynamic values to a multi-line string you can use interpolation by adding the variables with curly braces within the string and then using <i>string.Format()</i> to tell it to replace those with the values I provide.</p><pre class="crayon-plain-tag">string twiml = @"
&lt;Response&gt;
    &lt;Dial&gt;
        &lt;Number&gt;{0}&lt;/Number&gt;
    &lt;/Dial&gt;
&lt;/Response&gt;
";
return string.Format(twiml, To));</pre><p>So much more elegant right? My string remains the same but I can now replace values in it in compile time and just keep increasing the number within the curly braces.</p><p>Let’s kick it up a notch and say your string has attributes. We’d now be looking at adding speechmarks in each of them as such:</p><pre class="crayon-plain-tag">string twiml = @"
&lt;Response&gt;
    &lt;Dial callerId="{0}"&gt;
        &lt;Number&gt;{1}&lt;/Number&gt;
    &lt;/Dial&gt;
&lt;/Response&gt;
";
return string.Format(twiml, CallerId, To);</pre><p>Unfortunately it would also mean your code is now broken and you will start getting something like <i>CS1002: ; expected</i>. To go around that just make sure you double the speechmarks wherever you need them within your string.</p><pre class="crayon-plain-tag">string twiml = @"
&lt;Response&gt;
    &lt;Dial callerId=""{0}""&gt;
        &lt;Number&gt;{1}&lt;/Number&gt;
    &lt;/Dial&gt;
&lt;/Response&gt;
";
return string.Format(twiml, CallerId, To);</pre><p>And that will make your code work again and best of all – look really neat!</p> ]]></content:encoded> <wfw:commentRss>https://www.placona.co.uk/1524/dotnet/multi-line-c-sharp-strings/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>I&#8217;m joining Twilio</title><link>https://www.placona.co.uk/1498/conferences/im-joining-twilio/</link> <comments>https://www.placona.co.uk/1498/conferences/im-joining-twilio/#comments</comments> <pubDate>Thu, 16 Oct 2014 13:11:59 +0000</pubDate> <dc:creator><![CDATA[Marcos Placona]]></dc:creator> <category><![CDATA[Conferences]]></category> <category><![CDATA[General Techie Stuff]]></category> <category><![CDATA[Technology]]></category> <guid
isPermaLink="false">http://www.placona.co.uk/?p=1498</guid> <description><![CDATA[Reading time: 2 &#8211; 2 minutes So the time has come for me to move on and accept a new challenge. As of the October 20th,  I&#8217;ll be joining Twilio as a Developer Evangelist. Twilio has been no stranger to me for quite a while now,  and when I saw an open position in their [&#8230;]]]></description> <content:encoded><![CDATA[<p>Reading time: 2 &#8211; 2 minutes</p><p>So the time has come for me to move on and accept a new challenge. As of the October 20th,  I&#8217;ll be joining <a
title="Twilio" href="https://www.twilio.com/" target="_blank">Twilio</a> as a Developer Evangelist.</p><p>Twilio has been <a
title="Twilio-Dart" href="http://github.com/mplacona/twilio-dart">no stranger</a> <a
title="Sending and Receiving SMS messages with Dart" href="http://www.placona.co.uk/1467/open-source/sending-and-receiving-sms-messages-with-dart/">to me</a> for quite a while now,  and when I saw an open position in their <a
href="http://ahoy.twilio.com/heroes">devangelism team</a>,  I wasted no time and applied for it.</p><p>The whole process took a bit of time, but both Twilio and I were quite keen to make sure we would be a good fit for each other.</p><p>I had a number of telephone interviews,  and then flew over to <a
title="Twilio HQ 3.0" href="http://www.twilio.com/blog/2013/05/introducing-twilio-hq-3-0-our-brand-new-office.html">Twilio HQ 3.0</a> for the final round of interviews. The process was quite thrilling,  and I got so excited about it, this was the only company I actually applied for. Halfway the interview process, and after having met and spoken to some of the most clever people I have ever spoken with, I knew I wanted nothing but to work  with them.</p><p>I am supper excited with the prospect of not only writing  lot of code and working with some amazingly clever people, but also helping other developers writing some kick a$$ code in conferences, meetups, hackatons, stackoverflow&#8230;. or the pub.</p><p>Also, I will loudly and proudly wear my Twilio jacket to make sure people know they can approach me to have a chat about any Twilio integration, development in general, or life if they fancy it.</p><p>Here&#8217;s an example of what I will be doing.</p><p><iframe
width="676" height="380" src="https://www.youtube.com/embed/p3gcD0Jdqe0?feature=oembed" frameborder="0" allowfullscreen></iframe></p><p>So keep tuned, and get in touch!</p> ]]></content:encoded> <wfw:commentRss>https://www.placona.co.uk/1498/conferences/im-joining-twilio/feed/</wfw:commentRss> <slash:comments>7</slash:comments> </item> <item><title>Dart Pub packages stats</title><link>https://www.placona.co.uk/1489/python/dart-pub-packages-stats/</link> <comments>https://www.placona.co.uk/1489/python/dart-pub-packages-stats/#respond</comments> <pubDate>Mon, 21 Jul 2014 14:56:38 +0000</pubDate> <dc:creator><![CDATA[Marcos Placona]]></dc:creator> <category><![CDATA[Dart]]></category> <category><![CDATA[Open Source]]></category> <category><![CDATA[Python]]></category> <guid
isPermaLink="false">http://www.placona.co.uk/?p=1489</guid> <description><![CDATA[Reading time: 2 &#8211; 2 minutes So modulecounts came to my attention, and I thought the idea was pretty neat. I then contacted Erik (the author), and asked if he would mind also adding Dart. He replied saying he wouldn&#8217;t mind, but quite rightly pointed out there seemed to be no way on Dart&#8217;s package [&#8230;]]]></description> <content:encoded><![CDATA[<p>Reading time: 2 &#8211; 2 minutes</p><p>So <a
href="http://modulecounts.com">modulecounts</a> came to my attention, and I thought the idea was pretty neat.</p><p>I then contacted Erik (the author), and asked if he would mind also adding Dart.</p><p>He replied saying he wouldn&#8217;t mind, but quite rightly pointed out there seemed to be no way on Dart&#8217;s package manager to actually find out how many packages were live.</p><p>I <a
href="https://plus.google.com/111557456465418142877/posts/UonWh4dd2hx">asked some community members</a> on G+, and while they seemed to have some solutions that kinda worked, there didn&#8217;t seem to be anything accurate or likely to work every time.</p><p>My solution was to then quickly knock-up a scraper up that would navigate through all pages on the website, grab some information and counts, aggregate and then generate a JSON output that could then be used by anyone trying to get some package information.</p><p>The JSON package is generated once a day as to not overload the website.</p><p>I then created a very simple app-engine client application that consumes the JSON packet, and shows information about it.</p><p>Check it out here: <a
href="http://pub-stats.appspot.com" class="broken_link">http://pub-stats.appspot.com</a></p><p>Source code can also be seen in my GitHub account: <a
href="https://github.com/mplacona/pub-stats">https://github.com/mplacona/pub-stats</a></p><p>I have also exposed another endpoint for anyone wanting to use the JSON packet on their applications.</p><p>The packet is also cached daily, to make sure my app-engine account doesn&#8217;t get abused <img
src="https://s.w.org/images/core/emoji/2.4/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p><p>You can see the JSON endpoint here: <a
href="http://pub-stats.appspot.com/json" class="broken_link">http://pub-stats.appspot.com/json</a></p><p>Collaboration and pull requests welcome!</p> ]]></content:encoded> <wfw:commentRss>https://www.placona.co.uk/1489/python/dart-pub-packages-stats/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Sending and Receiving SMS messages with Dart</title><link>https://www.placona.co.uk/1467/open-source/sending-and-receiving-sms-messages-with-dart/</link> <comments>https://www.placona.co.uk/1467/open-source/sending-and-receiving-sms-messages-with-dart/#comments</comments> <pubDate>Fri, 04 Jul 2014 10:12:32 +0000</pubDate> <dc:creator><![CDATA[Marcos Placona]]></dc:creator> <category><![CDATA[Dart]]></category> <category><![CDATA[Open Source]]></category> <guid
isPermaLink="false">http://www.placona.co.uk/?p=1467</guid> <description><![CDATA[Reading time: 5 &#8211; 8 minutes I wanted to be able to send SMS messages with Dart, and because it doesn&#8217;t actually support it natively (not that I would expect it to anyway), I decided to write a library that allows me to do just that. The library itself is a wrapper to the Twilio [&#8230;]]]></description> <content:encoded><![CDATA[<p>Reading time: 5 &#8211; 8 minutes</p><p><img
class="aligncenter size-full wp-image-1468" src="http://www.placona.co.uk/wp-content/uploads/2014/07/dart_sms.png" alt="Dart - SMS example" width="695" height="170" srcset="https://www.placona.co.uk/wp-content/uploads/2014/07/dart_sms.png 695w, https://www.placona.co.uk/wp-content/uploads/2014/07/dart_sms-300x73.png 300w, https://www.placona.co.uk/wp-content/uploads/2014/07/dart_sms-676x165.png 676w" sizes="(max-width: 695px) 100vw, 695px" /></p><p>I wanted to be able to send SMS messages with Dart, and because it doesn&#8217;t actually support it natively (not that I would expect it to anyway), I decided to write a library that allows me to do just that.</p><p>The library itself is a wrapper to the <a
title="Twilio API" href="https://www.twilio.com/docs/api/rest">Twilio API</a>, which is a wicked service that allows you to not only send or receive SMS/MMS messages, but also lets you make phone calls, start conference calls etc, all through their API. This offers immense scope to build applications on top of, since you could build an entire telecommunications central on top of their infrastructure without having to invest largely on buying and maintaining your own kit.</p><p>The principle is that all you should need to do before you can get coding, is <a
title="Create a Twilio account" href="https://www.twilio.com/" target="_blank">crate a Twilio account</a>, and make a note of the account ID and the token it will provide you with. After that, you can get coding.</p><h3><span
style="text-decoration: underline;">Intro</span></h3><p>In a Dart application, you can do the following to get the library installed:</p><ol><li>Add a dependency to <code>twilio_dart</code> to your pubspec.yaml</li><li>Run <code>pub get</code></li></ol><p>With the library now installed on your application, you can start using it as such:</p><pre class="brush: java; title: ; notranslate">
import 'package:twilio_dart/twilio.dart';
//
var key = &quot;your_twilio_key&quot;;
var authToken = &quot;your_auth_token&quot;;
var version = &quot;2010-04-01&quot;;
Twilio twilio = new Twilio(key, authToken, version);</pre><p>This gives you a Twilio object, and you can use that to call the methods in the API. Make sure you replace<strong> key</strong> and <strong>authToken</strong> with the appropriate values provided upon registration with Twilio. You can also find them on <a
title="Twilio account dashboard" href="https://www.twilio.com/user/account" target="_blank">your dashboard</a>.</p><p>Everything being OK so far, you should now be able to actually send an SMS message using the number Twilio gave you when you created your account. You can also find this on your Twilio account under <a
title="Twilio numbers" href="https://www.twilio.com/user/account/phone-numbers/incoming" target="_blank">the numbers section</a>.</p><h3><span
style="text-decoration: underline;">Sending</span></h3><p>An SMS message is composed of three main parts:</p><ol><li>A <strong>from number</strong> &#8211; this should be the number Twilio provided you.</li><li>A <strong>to number</strong> &#8211; this can be any number capable of receiving text messages (i.e. your mobile number).</li><li>A <strong>message</strong> &#8211; This is the text message you want to send.</li></ol><pre class="brush: java; title: ; notranslate">var from = &quot;your_twilio_phone&quot;;
var to = &quot;your_mobile_number&quot;;
var body = &quot;Look ma! Dart can now send SMS's in under 15 lines&quot;;</pre><p>All there is to do now is actually try and send this message. To do so, we will use the s<code>endSMS</code> method. The signature for it is as follows:</p><pre class="brush: plain; title: ; notranslate">Future sendSMS(String from, String to, String body, [String mediaUrl = null])</pre><p>So straight away we know this method will return a <a
title="Dart - Futures" href="https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart:async.Future" target="_blank">Future</a>, and that it takes a <strong>from</strong>, a <strong>to</strong>, a <strong>body</strong>, and optionally the URL for an image, which will then turn your message into an <abbr
title='Multimedia Messaging Service' rel='tooltip'>MMS</abbr> by attaching that media directly to your message.</p><p>Therefore our code should look like the following when completed:</p><pre class="brush: java; title: ; notranslate">import 'package:twilio_dart/twilio.dart';
main() {
    var key = &quot;your_twilio_key&quot;;
    var authToken = &quot;your_auth_token&quot;;
    var version = &quot;2010-04-01&quot;;
    var from = &quot;your_twilio_phone&quot;;
    var to = &quot;your_mobile_number&quot;;
    var body = &quot;Look ma! Dart can now send SMS's in under 15 lines&quot;;
    //
    //create a new twilio object
    Twilio twilio = new Twilio(key, authToken, version);
    //
    // Send SMS for LOLZ
    twilio.sendSMS(from, to, body).then((response) =&gt; print(&quot;Your message has been sent!&quot;)).catchError((error) =&gt; print(error.toString()));
}</pre><p>Which even with all the line breaks and comments, still is just 15 lines.</p><p>If you execute this code, you will be able to verify two things:</p><ul><li>you&#8217;ve now got a new message on the phone you&#8217;ve chosen</li><li>under your Twilio account, you will also be able to read this message if you <a
title="Twilio - View logs" href="https://www.twilio.com/user/account/log/messages" target="_blank">view the logs</a>.</li></ul><h3><span
style="text-decoration: underline;">Listing</span></h3><p>I bet you&#8217;re somehow impressed by now as to how little you actually had to code to get our little application to send an SMS message. But we need a way to be able to retrieve those messages from the server without having to have a device in our hands all the time. the next thing we&#8217;re going to do, is come up with a way to list our messages. We can do that by using the method <code>readSMSList</code>, which does exactly what it says in the tin, it will give you a list of all the SMS messages in an account.</p><pre class="brush: java; title: ; notranslate">twilio.readSMSList().then((response){
        JSON.decode(response)['messages'].forEach((e) =&gt; print(e));       
    }).catchError((error) =&gt; print(error.toString()));</pre><h3><span
style="text-decoration: underline;">Reading</span></h3><p>Very simple and very neat. Get a JSON packet back, and iterate through the results. Each of the messages has a <strong>sid</strong>, which is the ID for this message, so the next thing we need to do, is to be able to drill down to each of the messages from a list of messages.</p><p>To do so, we will use the method <code>readSMS</code>, which takes a message id as a parameter, and returns its full contents.</p><pre class="brush: plain; title: ; notranslate">twilio.readSMS(sId).then((response) =&gt; print(response.toString())).catchError((error) =&gt; print(error.toString()));</pre><p>And the above will give you all the information pertaining a single message.</p><h3><span
style="text-decoration: underline;">Wrap up&#8230;</span></h3><p>So in this article, we&#8217;ve gone through the following:</p><ul><li>how to send an SMS message with Dart through the Twilio API by using the method sendSMS.</li><li>how to read a list of received messages from the server by using the method readSMSList.</li><li>how to read the contents of a single message by using the method readSMS.</li></ul><p>The source code to the library can be found on my <a
title="Twilio-Dart" href="https://github.com/mplacona/twilio-dart" target="_blank">GitHub account</a> along with samples and documentation.</p> ]]></content:encoded> <wfw:commentRss>https://www.placona.co.uk/1467/open-source/sending-and-receiving-sms-messages-with-dart/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Creating files with Dart</title><link>https://www.placona.co.uk/1448/open-source/dart/creating-files-with-dart/</link> <comments>https://www.placona.co.uk/1448/open-source/dart/creating-files-with-dart/#respond</comments> <pubDate>Sat, 03 May 2014 22:23:43 +0000</pubDate> <dc:creator><![CDATA[Marcos Placona]]></dc:creator> <category><![CDATA[Dart]]></category> <guid
isPermaLink="false">http://www.placona.co.uk/?p=1448</guid> <description><![CDATA[Reading time: &#60; 1 minute This is a very simple example of how to create files with Dart. I am working on another example that involves file manipulation, but thought I&#8217;d quickly post this one here as to have it out of the way. In this post I will show you quickly how to create [&#8230;]]]></description> <content:encoded><![CDATA[<p>Reading time: &lt; 1 minute</p><p>This is a very simple example of how to create files with Dart. I am working on another example that involves file manipulation, but thought I&#8217;d quickly post this one here as to have it out of the way.</p><p>In this post I will show you quickly how to create a text file using Futures in Dart. The example will:</p><ul><li>create the file</li><li>write some content to it synchronously</li><li>return a message when the contents have been written</li></ul><p>Our code will therefore go as follows:</p><p><img
class="alignnone wp-image-1453 size-full" src="http://www.placona.co.uk/wp-content/uploads/2014/05/dart_create_file_big.png" alt="Dart - Create File" width="751" height="302" srcset="https://www.placona.co.uk/wp-content/uploads/2014/05/dart_create_file_big.png 751w, https://www.placona.co.uk/wp-content/uploads/2014/05/dart_create_file_big-300x120.png 300w, https://www.placona.co.uk/wp-content/uploads/2014/05/dart_create_file_big-676x271.png 676w" sizes="(max-width: 751px) 100vw, 751px" /></p><p>The gist can also be found on <a
title="Create files in dart - Gist" href="https://gist.github.com/mplacona/a7fa2033a56e14471ebf">GitHub</a>.</p><p>&nbsp;</p> ]]></content:encoded> <wfw:commentRss>https://www.placona.co.uk/1448/open-source/dart/creating-files-with-dart/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Dart &#8211; Futures and HTTP requests</title><link>https://www.placona.co.uk/1439/open-source/dart/dart-futures-and-http-requests/</link> <comments>https://www.placona.co.uk/1439/open-source/dart/dart-futures-and-http-requests/#respond</comments> <pubDate>Tue, 29 Apr 2014 19:14:51 +0000</pubDate> <dc:creator><![CDATA[Marcos Placona]]></dc:creator> <category><![CDATA[Dart]]></category> <guid
isPermaLink="false">http://www.placona.co.uk/?p=1439</guid> <description><![CDATA[Reading time: 2 &#8211; 3 minutes I wrote a little article about how to retrieve  from GitHub, and +Seth Ladd quite rightly pointed something out. Let me elaborate a little bit on what he means. In my sample code (cut down for brevity, but you can still check it out here), I am indeed using [&#8230;]]]></description> <content:encoded><![CDATA[<p>Reading time: 2 &#8211; 3 minutes</p><p>I <a
title="Retrieving GitHub’s gists with Dart" href="http://www.placona.co.uk/1433/open-source/retrieving-githubs-gists-with-dart/">wrote a little article</a> about how to retrieve <abbr
title='code snippets' rel='tooltip'>gists</abbr> from GitHub, and <a
title="Retrieving GitHub’s gists with Dart" href="http://www.placona.co.uk/1433/open-source/retrieving-githubs-gists-with-dart/">+Seth Ladd</a> quite rightly pointed something out.</p><p><img
class="alignnone size-full wp-image-1440" src="http://www.placona.co.uk/wp-content/uploads/2014/04/seth_makes_a_good_point.png" alt="Seth Ladd makes a good point" width="517" height="156" srcset="https://www.placona.co.uk/wp-content/uploads/2014/04/seth_makes_a_good_point.png 517w, https://www.placona.co.uk/wp-content/uploads/2014/04/seth_makes_a_good_point-300x90.png 300w" sizes="(max-width: 517px) 100vw, 517px" /></p><p>Let me elaborate a little bit on what he means.</p><pre class="brush: java; highlight: [4,5,6]; title: ; notranslate"> getGistsForUser(String user){
this.user = user;
var url = &quot;https://api.github.com/users/${this.user}/gists&quot;;
http.get(url)
  .then(_processResults)
  .catchError(_handleError);
}</pre><p>In my sample code (cut down for brevity, but you can still check it out <a
title="Retrieving GitHub’s gists with Dart - Gist" href="https://gist.github.com/mplacona/11332667" target="_blank">here</a>), I am indeed using Futures, so the thread is not locked to this request, and my code could be happily doing other things. However, I&#8217;m not informing the client about this future, or allowing it to make use of it.</p><p>So when I make a request to it, I&#8217;m simply doing:</p><pre class="brush: java; title: ; notranslate">gists.getGistsForUser(username);</pre><p>Which works in this case as my <strong>getGistsForUser</strong> method is dealing with displaying the gists itself; therefore the client isn&#8217;t waiting as the method returns void.</p><p>If I then wanted to get my client know exactly when the method had returned, I would need to make changes to my code by simply making the method <strong>getGistsForUser</strong> return a Future. This is what the code would look like after making a few changes:</p><p>View the code on <a
href="https://gist.github.com/mplacona/11398580">Gist</a>.</p><p>As you can see, I&#8217;ve only updated a few things, but now my response is handled by my client.</p><p>To simplify, I have written a much simpler example that only handles an HTTP request, without prompting the user for any information.</p><p>View the code on <a
href="https://gist.github.com/mplacona/11398906">Gist</a>.</p><p>And this is how you go about returning futures from HTTP requests</p> ]]></content:encoded> <wfw:commentRss>https://www.placona.co.uk/1439/open-source/dart/dart-futures-and-http-requests/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> </channel> </rss>