Escaping code to be displayed in HTML/XHTML



    One of the most tedious things about blogging about Software Development is escaping your code so it can be displayed on your blog. This is especially true when it comes to XHTML (Blogger) as the parser might throw an exception and not display any of the page. One solution is to surround the code with <pre></pre> tags to alert the parser that the code is pre-formatted. However, this alone isn't simply enough especially when it comes to XHTML. So are we left to manually go through the code and escape every character that needs to be? No, I've developed a script that will handle this task.

What does it mean to escape a character?

    There are certain characters that cannot be used in an HTML/XHTML document as they already have a distinct purpose. For instance, the less than (<) and greater than (>) symbols are used to denote the start and end of a tag respectively (<body>). Therefore when we use them within our text, the parser believes they are the start and end of a tag which is obviously not the case. So, we would have to replace them with their "escaped" alternatives, &lt; and &gt; respectively.

Automating the process

    Instead of going through the code and manually changing out characters for their escaped equivalents, I've developed a script that can automate this process. I also created a web app for ease of use that can be found here. And here's the code on GitHub. Here's an example:

Input:

for(int i = 0; i < 10; i++){}

Output:

for(int i = 0; i &lt; 10; i++){}

    In the above example it only needed to escape the less than symbol, <, to its escaped equivalent, &lt;. But in more realistic scenarios it might have a whole class to iterate through and escape characters. Also, the application surrounds the text output in pre and code tags for proper HTML5 semantics and use.

Conclusion

    Now there is a tool for simply escaping code to be displayed in HTML/XHTML. I use it for my blog when I need to show code examples. You are free to use it as well, Enjoy!

Face detection and live filters


    Live video filters are becoming a popular trend fueled by Facebook (through their purchase of Msqrd) and Snapchat incorporating the features into their apps. These filters apply images or animations to your face using face tracking software. This technology has been around for awhile but is becoming increasingly more common due to the powerful CPU's that our mobile phones now have. Google provides an API that provides face tracking abilities through the Google Play Services library called Mobile Vision. I'm going to use their API to build a basic live filter app. The end result will look something like this:


    The bounding box wraps around the detected face and the sunglasses are the filter I chose (which is just a PNG image) which are drawn over the eyes. You could use any PNG image (with alpha for the background) you want, you will just have to adjust the layout according to where the image should be displayed. As you move your head, the box and sunglasses are redrawn in the correct spot. This app is hardly perfect and you may notice that the image is a bit jittery (especially when you blink) but it's a fun project to mess around with. This app is going to be built off of Google's FaceTracker sample for the library, so build that first.

    Now, in the Graphic abstract class inside the GraphicOverlay class add a getter for the mOverlay field:


public GraphicOverlay getOverlay(){
    return mOverlay;
}


    This will allow us to obtain a reference to the context through the parent GraphicOverlay object within a Graphic class. Next, in the FaceGraphic class specify two global instance fields:


private Bitmap bitmap;
private Bitmap sunglasses;


    The bitmap field will be a reference to the original Bitmap we create and the sunglasses field is just a scaled version of that Bitmap. When the Graphic class is updated with the new Face information, we have to scale the image to match the size of the face and move it to the correct position. Having two Bitmap objects will be helpful for this re-sizing process by retaining the image quality. Next, in the bottom of the FaceGraphic constructor, we instantiate the Bitmap objects:


bitmap = BitmapFactory.decodeResource(getOverlay().getContext().getResources(), R.drawable.sunglasses);
sunglasses = bitmap;


    Then we update the size of the sunglasses Bitmap in the updateFace method of the FaceGraphic class. So, in the updateFace method before the postInvalidate() call, place the following code:


sunglasses = Bitmap.createScaledBitmap(bitmap, (int) scaleX(face.getWidth()),
                (int) scaleY(((bitmap.getHeight() * face.getWidth()) / bitmap.getWidth())), false);


   
    Finally, we draw the image to the screen. So, replace the draw method in the FaceGraphic class with the following code:


@Override
public void draw(Canvas canvas) {
    Face face = mFace;
    if (face == null) {
        return;
    }
    float x = translateX(face.getPosition().x + face.getWidth() / 2);
    float y = translateY(face.getPosition().y + face.getHeight() / 2);
    // Draws a bounding box around the face.
    float xOffset = scaleX(face.getWidth() / 2.0f);
    float yOffset = scaleY(face.getHeight() / 2.0f);
    float left = x - xOffset;
    float top = y - yOffset;
    float right = x + xOffset;
    float bottom = y + yOffset;
    canvas.drawRect(left, top, right, bottom, mBoxPaint);
    //Get the left eye to place the sunglasses over the eyes
    float eyeY = top + sunglasses.getHeight() / 2;
    for(Landmark l : face.getLandmarks()){
        if(l.getType() == Landmark.LEFT_EYE){
            eyeY = l.getPosition().y + sunglasses.getHeight() / 2;
        }
    }
    canvas.drawBitmap(sunglasses, left, eyeY, new Paint());
}


    Now run the code and you'll see a box drawn around your head and the sunglasses image over your eyes even when you move. Note: I didn't provide a sunglasses image but you can easily get one from Google. Also, if the camera isn't the front-facing camera, in the FaceTrackerActivity, at the bottom of the createCameraSource() method, change the setFacing() method call to
CameraSource.CAMERA_FACING_FRONT:


mCameraSource = new CameraSource.Builder(context, detector)
        .setRequestedPreviewSize(640, 480)
        .setFacing(CameraSource.CAMERA_FACING_FRONT)
        .setRequestedFps(30.0f)
        .build();


    And you're finished. Go ahead and mess around by adding and changing images.

Easy View Injection with Butter Knife






    Butter Knife is an easy to use View Injection library. It significantly cleans up some boiler-plate code, specifically dealing with setting up Views. For whatever reason I haven't used it until recently but it is easy to adapt to and greatly reduces the amount of code I have to write. As an aside I would like to point out that Square really does a great job with their libraries (Butter Knife is a library by Jake Wharton a developer at Square). Not only are they coded really well but they're also open source and they have so many significant ones (Picasso, OkHttp, Retrofit, Dagger, etc).

Note: In some of my code snippets I use private variables for the Views but when using Butter Knife, the Views must be public. 

    Butter Knife is so easy to use you really don't need a tutorial since they cover most use cases on its Github page. But either way we're going to have a look at how to use the library and compare it to how you would normally code without it. First, let's have a look at the way we would normally instantiate a View from a layout resource file:


TextView title = (TextView) findViewById(R.id.title);


    We use the Activity class' findViewById() method, passing it an integer ID as a parameter, to get an instance of a View but we have to cast it to the specific View it is (TextView). Now, let's take a look at how we would do this using Butter knife:


@Bind(R.id.title) TextView title;
ButterKnife.bind(this);


    It might not be a significant decrease in the amount of code we have to type (especially when considering the ButterKnife.bind() call) but in the long run it is much better. Also, programmers tend to declare their View variables in the beginning of the class (making them instance variables) and then instantiate them later in the onCreate() method. This causes the amount of lines used to double and makes it harder to read. Which brings up another good reason to use Butter Knife: it keeps everything in one place so no need to go looking for the instantiation of a variable. So, let's look at a more realistic example, first how we normally would code it:


public class MainActivity extends AppCompatActivity{
    private TextView title;
    private TextView date;
    private TextView content;
    private ImageView image;
    private Button like;
    private Button dislike;
    private Button comment;
    
    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);
        title = (TextView) findViewById(R.id.title);
        date = (TextView) findViewById(R.id.date);
        content = (TextView) findViewById(R.id.content);
        image = (ImageView) findViewById(R.id.image);
        like = (Button) findViewById(R.id.like);
        dislike = (Button) findViewById(R.id.dislike);
        comment = (Button) findViewById(R.id.comment);
    }

}


    And this is what it would like if we used Butter Knife:


public class MainActivity extends AppCompatActivity{
    @Bind(R.id.title) private TextView title;
    @Bind(R.id.date) private TextView date;
    @Bind(R.id.content) private TextView content;
    @Bind(R.id.image) private ImageView image;
    @Bind(R.id.like) private Button like;
    @Bind(R.id.dislike) private Button dislike;
    @Bind(R.id.comment) private Button comment;

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);
        ButterKnife.bind(this);
    }

}


    That's much better. If you programmed a decent amount you would jump at any chance to cut down on redundant code and the need to type it out. Butter Knife has more features, such as, binding text to TextView's and images to ImageView's but we won't look at them here.

Tinder mockup, Retrofit, and Gson



    It's ironic that the larger a company becomes, even with all the resources it obtains, the slower and less influential it is. This is why larger company's tend to buy out the newest start-ups. But once owned by a larger company, the company hardly innovates and is very slow to release updates (perhaps due to the internal bureaucracy). Sometimes this results in a sturdy yet not so exciting product. However, sometimes I've noticed it results in a worse product (maybe due to them overly complicating their product in an attempt to accommodate as much people as possible). I'm not sure if this is the case with Tinder (I don't know if they were bought out by any larger company) but I know they have become very popular (maybe?) and I have noticed a seemingly steady decline in the quality of their product.

    Over time, I have noticed many annoying problems with their app. I have provided feedback to them via the app's feedback option and have even speculated as what can be the cause of their issue and a possible solution how to fix it. Of course I didn't receive a response (they might not even check their feedback or they just might not have the time to get back to everyone, no worries just thought I'd help). But as time went on and updates rolled out, I was still facing a lot of these same issues (mostly UI problems) which somewhat annoyed me. So, I decompiled their APK and had a look at their source code. It was hard to get a complete picture of what was going since the code was obviously obfuscated but I did see enough to get a gist.

    It seemed that they had Fragments for every little View type and interaction which could be what was causing most of the problems (they must not be properly handling the switching of these fragments). One issue I noticed with the app is that sometimes the images don't load. I was surprised to find that they use the Picasso library because that is a really good library (I use it often and never faced this issue), so it must be an issue with how they handle using the library. I might not been able to locate the exact problems with their code but all this snooping around got me thinking how would I go about creating the client side app. So I created it. 

    I just hacked up a quick and crude version of the Tinder app today. Obviously theirs is more complex (which creates more room for errors) but I just wanted to hack up the gist of it. The code is mainly just UI and structural. I didn't code the server side logic and I didn't go into great detail; theres no transition animations or anything of that nature (I don't want to spend more than one weekend day on this). I just wanted to create a quick mockup of the main experience the app offers. So here's the logic flow:

User opens app >

    Splash Activity appears, uses Facebook SDK to check if the user is signed in >

        Signed In? >

            Yes >

                 MainActivity

             No >

                  LoginActivity

    The MainActivity is the Activity that contains the swipeable cards. I used the Facebook SDK for authentication but since this is just a mockup app I'm not registering an App ID and I'm not coding the server-side logic, so I comment blocked that logic out and just passed over to the MainActivity. The MainActivity is an Activity with a DrawerLayout to slide open for the side menu, a custom Toolbar with a TabLayout for the tabs, and a ViewPager so you can slide between the different Fragments with the TabLayout in the Toolbar. There's just two Fragments the one containing the cards and the one containing the matches. Luckily there's already a library for the cards so I don't have to code the custom Views and Adapters (which shouldn't be too hard just time consuming). And I'll just use FloatingActionButtons from this library for the dislike, like, and superlike buttons since they're circular and have an elevation to them. I'll also being using Retrofit and Gson for handling the REST requests to the https://randomuser.me/ service that will randomly populate the cards with values and pictures.

All the code can be found here.

First lets have a look at our MainActivity (which I call HomeActivity) layout:


    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!-- The main content view -->
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <include
                android:id="@+id/toolbar"
                layout="@layout/tab_toolbar" />

            <android.support.v4.view.ViewPager
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/pager"
                android:layout_width="match_parent"
                android:layout_height="0px"
                android:layout_weight="1" />

        </LinearLayout>

        <!-- The navigation drawer -->
        <android.support.design.widget.NavigationView
            android:id="@+id/navigation_view"
            android:layout_height="match_parent"
            android:layout_width="wrap_content"
            android:layout_gravity="start"
            app:menu="@menu/drawer" />

    </android.support.v4.widget.DrawerLayout>


    As we can see the layout is pretty simple and straightforward. The root view is a DrawerLayout so we can have a slide out menu. The first child of the DrawerLayout is the actual main view, here we have a LinearLayout ViewGroup which has a Toolbar (this is "removed" from the "main" view and set as the ActionBar later in code) and a ViewPager as children. The second child of the DrawerLayout is a NavigationView from the design support library, this view will be the view for the slide out menu, it'll contain a list of menu options as well as a header view displaying the user's information. Now, the Activity class:


public class HomeActivity extends AppCompatActivity {
    private static final String TAG = HomeActivity.class.getSimpleName();
    private Toolbar toolbar;
    private DrawerLayout drawerLayout;
    private ActionBarDrawerToggle drawerToggle;
    private NavigationView navigationView;
    private View headerView;
    private ViewPager viewPager;
    private TabLayout tabLayout;

    @Override
    @SuppressWarnings("deprecation")
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.home);
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        navigationView = (NavigationView) findViewById(R.id.navigation_view);
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem) {
                menuItem.setChecked(false);
                drawerLayout.closeDrawers();
                //Add logic to perform the appropriate action depending on what item was selected
                switch(menuItem.getItemId()){
                    case R.id.discover_settings:
                        return true;
                    case R.id.app_settings:
                        return true;
                    case R.id.help:
                        return true;
                    case R.id.feedback:
                        return true;
                    case R.id.tinder_plus:
                        return true;
                }
                return false;
            }
        });
        headerView = LayoutInflater.from(this).inflate(R.layout.navigation_header, navigationView, false);
        headerView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //TODO Load the Users profile
            }
        });
        navigationView.addHeaderView(headerView);
        //TODO Add logic to display the users information into the header view
        drawerToggle = new ActionBarDrawerToggle(
                this,                  /* host Activity */
                drawerLayout,         /* DrawerLayout object */
                toolbar,  /* nav drawer icon to replace 'Up' caret */
                R.string.drawer_open,  /* "open drawer" description */
                R.string.drawer_close  /* "close drawer" description */
        ) {
            /**
             * Called when a drawer has settled in a completely closed state.
             */
            public void onDrawerClosed(View view) {
                super.onDrawerClosed(view);
            }

            /**
             * Called when a drawer has settled in a completely open state.
             */
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
            }
        };
        // Set the drawer toggle as the DrawerListener
        drawerLayout.addDrawerListener(drawerToggle);
        //Set up the tabs and swipeable views
        viewPager = (ViewPager) findViewById(R.id.pager);
        ScreenSlidePagerAdapter adapter = new ScreenSlidePagerAdapter(getSupportFragmentManager(), this);
        viewPager.setAdapter(adapter);
        tabLayout = (TabLayout) toolbar.findViewById(R.id.sliding_tabs);
        tabLayout.setupWithViewPager(viewPager);
        //Set up the icons
        for (int i = 0; i < tabLayout.getTabCount(); i++) {
            switch(i){
                default:
                case 0:
                    tabLayout.getTabAt(i).setIcon(R.drawable.tinder_icon);
                    break;
                case 1:
                    tabLayout.getTabAt(i).setIcon(R.drawable.speech_bubbles_gray);
                    break;
            }
        }
        getSupportActionBar().setDisplayShowHomeEnabled(false);
        getSupportActionBar().setDisplayShowTitleEnabled(false);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        // Sync the toggle state after onRestoreInstanceState has occurred.
        drawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        drawerToggle.onConfigurationChanged(newConfig);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Pass the event to ActionBarDrawerToggle, if it returns
        // true, then it has handled the app icon touch event
        if (drawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        // Handle your other action bar items...
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onBackPressed() {
        if(drawerLayout.isDrawerOpen(GravityCompat.START)){
            drawerLayout.closeDrawer(GravityCompat.START);
        }else{
            super.onBackPressed();
        }
    }


    private class ScreenSlidePagerAdapter extends FragmentPagerAdapter {
        private Context context;

        public ScreenSlidePagerAdapter(FragmentManager fm, Context context){
            super(fm);
            this.context = context;
        }

        @Override
        public Fragment getItem(int position) {
            switch(position){
                default:
                case 0:
                    return CardFragment.newInstance();
                case 1:
                    return MatchFragment.newInstance();
            }
        }

        @Override
        public int getCount() {
            return 2;
        }

        @Override
        public CharSequence getPageTitle(int position) {
           return "";
        }

    }


}


    This class is mainly just structural code. In the overrided onCreate method we set the Toolbar as the support action bar with the setSupportActionBar(toolbar) method call. We set up an item selected listener on our NavigationView. We set a custom view as our header view to the NavigationView. We add a DrawerListener to the DrawerLayout just incase we want to listen to events. We sync the ViewPager with a FragmentPagerAdapter and our custom Toolbar which contains a TabLayout. And the rest of the code in the class is just handling events and such. The FragmentPagerAdapter internal class that we set up is what changes the view to the appropriate Fragment. So, now we can set up the Fragments. We'll focus on the main Fragment, CardFragment:


public class CardFragment extends Fragment {
    private com.andtinder.view.CardContainer cardContainer;
    private UserCardAdapter adapter;
    private FloatingActionButton dislike;
    private FloatingActionButton superlike;
    private FloatingActionButton like;

    public static CardFragment newInstance(){
        return new CardFragment();
    }

    @Override
    @SuppressWarnings("deprecation")
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        View v = inflater.from(container.getContext()).inflate(R.layout.card_fragment, container, false);
        cardContainer = (CardContainer) v.findViewById(R.id.card_container);
        cardContainer.setOrientation(Orientations.Orientation.Disordered);
        adapter = new UserCardAdapter(getContext());
        cardContainer.setAdapter(adapter);
        dislike = (FloatingActionButton) v.findViewById(R.id.dislike);
        superlike = (FloatingActionButton) v.findViewById(R.id.superlike);
        like = (FloatingActionButton) v.findViewById(R.id.like);
        //set up these fields in code because the library doesn't properly handle the xml custom attributes
        dislike.setColorNormal(getContext().getResources().getColor(R.color.tinder_red));
        dislike.setColorPressed(getContext().getResources().getColor(R.color.tinder_red));
        dislike.setIconDrawable(getContext().getResources().getDrawable(R.drawable.tinder_dislike));
        dislike.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //TODO add logic
            }
        });
        superlike.setColorNormal(getContext().getResources().getColor(R.color.tinder_blue));
        superlike.setColorPressed(getContext().getResources().getColor(R.color.tinder_blue));
        superlike.setIconDrawable(getContext().getResources().getDrawable(R.drawable.superlike));
        superlike.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //TODO add logic
            }
        });
        like.setColorNormal(getContext().getResources().getColor(R.color.tinder_green));
        like.setColorPressed(getContext().getResources().getColor(R.color.tinder_green));
        like.setIconDrawable(getContext().getResources().getDrawable(R.drawable.tinder_like));
        like.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //TODO add logic
            }
        });
        return v;
    }

}


Gson Deserialization

    So we're using randomuser.me to feed us random user information to display in our cards. The result comes back in the form of JSON (which is common). We're using Retrofit to make an interface for our HTTP API method call (randomuser.me/api). Retrofit comes with support for add on modules that can parse different forms of data, one of them being Gson (Google's JSON library). The Gson library can deserialize in two ways: a POJO (Plain Old Java Object) hierarchy mimicking the JSON response format (which it uses reflection to properly deserialize the JSON into the objects) and a custom JsonDeserializer interface you can provide to the Gson builder. I went with the former since its pretty straightforward. Let's have a look at the JSON response format we're dealing with here:


{
  results: [{
    user: {
      gender: "female",
      name: {
        title: "ms",
        first: "manuela",
        last: "velasco"
      },
      location: {
        street: "1969 calle de alberto aguilera",
        city: "la coruña",
        state: "asturias",
        zip: "56298"
      },
      email: "manuela.velasco50@example.com",
      username: "heavybutterfly920",
      password: "enterprise",
      salt: ">egEn6YsO",
      md5: "2dd1894ea9d19bf5479992da95713a3a",
      sha1: "ba230bc400723f470b68e9609ab7d0e6cf123b59",
      sha256: "f4f52bf8c5ad7fc759d1d4156b25a4c7b3d1e2eec6c92d80e508aa0b7946d4ba",
      registered: "1303647245",
      dob: "415458547",
      phone: "994-131-106",
      cell: "626-695-164",
      DNI: "52434048-I",
      picture: {
        large: "http://api.randomuser.me/portraits/women/39.jpg",
        medium: "http://api.randomuser.me/portraits/med/women/39.jpg",
        thumbnail: "http://api.randomuser.me/portraits/thumb/women/39.jpg",
      },
      version: "0.6"
      nationality: "ES"
    },
    seed: "graywolf"
  }]
}


    As we can see what we are returned is an object (within the "{}" brackets) with a "results" field. This "results" field is an array (within the "[]" brackets) of objects. Each of these objects has two fields "user" and "seed". The "seed" field is just a String and the "user" field is an object. We're only interested in some of the "user" object fields but as you can see some of those are also objects, such as the "name" field. So let's create our POJO's:


public class UserResult {
    private List<ResultObject> results;

    public UserResult(){

    }

    public UserResult(List<ResultObject> results){
        this.results = results;
    }

    public List<ResultObject> getResults() {
        return results;
    }

    public void setResults(List<ResultObject> results) {
        this.results = results;
    }

}


    The above class is the object that is returned from the API call which has the "results" field. The "results" field is an array of objects so in our Java class it's a List of type ResultObject which is the next POJO we define.


public class ResultObject {
    private User user;
    private String seed;

    public ResultObject(){

    }

    public ResultObject(User user, String seed){
        this.user = user;
        this.seed = seed;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public String getSeed() {
        return seed;
    }

    public void setSeed(String seed) {
        this.seed = seed;
    }

}


    The code above follows the same pattern as specified before. And finally our User object which contains some internal classes representing its fields.


public class User {
    private String gender;
    private Name name;
    private String email;
    private String username;
    private Picture picture;

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public Name getName() {
        return name;
    }

    public void setName(Name name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Picture getPicture() {
        return picture;
    }

    public void setPicture(Picture picture) {
        this.picture = picture;
    }

    public static class Name{
        private String title;
        private String first;
        private String last;

        public Name(){

        }

        public Name(String title, String first, String last){
            this.title = title;
            this.first = first;
            this.last = last;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getFirst() {
            return first;
        }

        public void setFirst(String first) {
            this.first = first;
        }

        public String getLast() {
            return last;
        }

        public void setLast(String last) {
            this.last = last;
        }

    }

    public static class Picture{
        private String large;
        private String medium;
        private String thumbnail;

        public Picture(){

        }

        public Picture(String large, String medium, String thumbnail){
            this.large = large;
            this.medium = medium;
            this.thumbnail = thumbnail;
        }

        public String getLarge() {
            return large;
        }

        public void setLarge(String large) {
            this.large = large;
        }

        public String getMedium() {
            return medium;
        }

        public void setMedium(String medium) {
            this.medium = medium;
        }

        public String getThumbnail() {
            return thumbnail;
        }

        public void setThumbnail(String thumbnail) {
            this.thumbnail = thumbnail;
        }

    }


}


Retrofit

    Retrofit is a pretty amazing library that let's you turn HTTP API's into Java Interfaces. This greatly simplifies performing REST requests and such putting the HTTP methods as Java methods. Here's how it works in our case: we create a Java Interface and define the relative endpoint and parameters for each method. We then use the Retrofit class to make an instance of our Interface and then we call our method we specified and to get a Call object which we use to execute our request and get a response. Here's the Interface:


public interface UserService {
    @GET("?results=amount")
    Call<UserResult> getUsers(@Query("results") int amount);
}


    Now we can use the Retrofit class to make an implementation of our interface. Retrofit can be called synchronously or asynchronously, if you call it synchronously in Android make sure to do it off the main UI thread (I do it in an AsyncTask). Here's the relevant code from the UserCardAdapter class:


private void loadUsers(){
        new AsyncTask<Void, Void, UserResult>(){
            @Override
            protected UserResult doInBackground(Void... params) {
                try {
                    Retrofit retrofit = new Retrofit.Builder()
                            .baseUrl("http://api.randomuser.me/")
                            .addConverterFactory(GsonConverterFactory.create()) //We're using Gson to deserialize our response
                            .build();
                    UserService service = retrofit.create(UserService.class); //Creates an implementation of our interface
                    Call<UserResult> call = service.getUsers(20); //Our method call returns our Call object of type UserResult
                    return call.execute().body();//execute our call object (blocking) and the body is our UserResult object
                }catch(Exception e){
                    e.printStackTrace();
                }
                return null;
            }
            @Override
            public void onPostExecute(UserResult result){
                if(result != null) {
                    //Take the result and add the User information to cards that can be swiped
                    Drawable defaultDrawable = getContext().getResources().getDrawable(R.drawable.tinder_icon);
                    User u;
                    for (ResultObject r : result.getResults()) {
                        u = r.getUser();
                        add(new CardModel(u.getName().getFirst(), u.getPicture().getLarge(), defaultDrawable));
                    }
                }
            }
        }.execute();
    }


    And that's all there is to it, the basis of a Tinder mockup application. Obviously, Tinder has more features, server-side logic, and animations. But this is a good starting point that if I had more interest, time, and resources for this project I could continue to develop. This post isn't to undermine Tinder and the work and innovation they have done but more just a proof of concept. I often look at apps and wonder "how did they code that and how would I go about it" (and if there's an error with the app, "how could I fix it"). I apologize for the "rantiness" (I know that's not a word) of this post I just was typing this as I was coding the project and I didn't want to spend more than one weekend day on it as I have other things I need to do, so, I rushed a little and didn't spell or grammar check. Hopefully, this was fun, interesting, and insightful for someone. 

Hosting portfolio site on GitHub Pages.


    Most software developers have a portfolio site where they can show off their projects, knowledge, code, and experiences. It's great to have when searching for a job because it's a chance to woo potential employers with your technical abilities. And it's a great little project that you can always update and experiment with. When I first created my portfolio site, I hosted it on AWS (Amazon Web Services) Elastic Beanstalk. Obviously, Elastic Beanstalk is overkill for a portfolio site since you shouldn't expect that much traffic where you would need a Load Balancer, but I chose to use it for the following reasons:

  • To become more familiar with Elastic Beanstalk (At the time I was preparing to launch an application to Elastic Beanstalk and this was a great starting point).

  • They offered a free tier for a year (Nowadays there is no need to pay for having a blog and I believe the same should be true for a portfolio site).

  • I had a contact form which was sent to the server where I used the Apache Commons Email API to send me an Email with the form information.

     Well, my free tier is up and I made the decision to migrate my website to a free host. The website is mostly static pages except for the contact form server side code. You would be surprised how hard it is to find a free host that allows custom domains and has some sort of transactional Email API. So, I finally decided on GitHub because they allow you to host a user website for free (they call them GitHub Pages) and you can even attach a custom domain. Since the code is just static pages (CSS, JS, HTML, and files) and there is no security issues (any website viewed can be deobfuscated if needed, so, hosting a website on a public repository is no different), this is a perfect service. To solve my Email problem I went with FormSpree. They provide a simple POST URL that you can submit your forms to and they will forward you the provided information to your email. You can even send it via JavaScript through an AJAX request (using JQuery):


    var name = document.getElementById("name").value;
    var email = document.getElementById("email").value;
    var message = document.getElementById("message").value;
    var obj = {"name": name, "_replyto": email, "message": message};
    $.ajax({
        url: "//formspree.io/youremail@email.com",
        type: "POST",
        data: obj,
        dataType: "json",
        success: function(){
            console.log("sent email");
            notify("Email", "Successfully Sent Message");
            clearForm();
        },
        error: function(jqXHR, textStatus, errorThrown){
            console.error("Error sending email: " + textStatus + " " + errorThrown);
            notify("Email", "Error Send Message");
            clearForm();
        }
    });

    To setup your website on GitHub, follow their simple tutorial. Just note that changes you make aren't instantly reflected and may take up to 30 minutes. And this is a good tutorial on how to get your domain name to link to your GitHub Pages website using the GoDaddy service. Just note that you will need to create an A record for both the IP's 192.30.252.153 and 192.30.252.154.

    Finally, I created a custom 404 page for my portfolio site that matched my site's theme and wasn't a generic one provided by GitHub. The code is pretty straightforward and can be found here. Here's what the page looks like:


It's meant to mimic an error dialog that you might see on a computer. Now my portfolio site is freely hosted by GitHub and I can make changes simply by making commits to my repository.