Why I started hating ios Framework



I am sorry ios developers. But yes, I don't like this Framework.

I am an Android developer and I am developing android apps for more than 2.5 years. I really enjoy developing Android apps and implementing it's new features. Things are pretty easy and very straight forward in this very cool Framework. As a developer You don't need to put very very extras efforts even for tedious things.

Four months back, my manager approached me and said We have to develop an ios app for our customers. As I am a mobile developer and I am always very open to learn new things. I said Why not?  We must do it. Question was how and how much time it will take? We decided to publish our app module by module and I was given 45 days to complete it's very first module including setup Mac machine for ios development.

After few days I started working on first module and before starting I was sure that things will be very similar to Android.
After a week

                          What the fuck! 
                          It's nothing like what was expected.

The very first problem I faced in managing widgets and their constraints in storyboards. I took a lot of hours to design a simple ViewController. 

Customization is not really easy task in ios. I used to bang my head on keyboard to customize things as per my requirements.

Most of the things what I needed in my project like Customized SegmentedControl, horizontal smooth progress view without timer and many more, I had to rely on pods.

Some methods can be called only from some standard methods. They won't work if You call them from some other methods.

And the worst part is working with UIcollectionView.  I am still stuck with this thing.
Everywhere it gives me run time warnings for constraint violation, I really don't know why? What I have done wrong? I tested every scenario in my xib file, but warnings are still there.
                        Using AutoLayout in UICollectionView was a really tedious task for me at least.
And I am still fighting with inserting new rows to the bottom of my UICollectionView, because it makes my screen blank just before inserting new cells and after adding them, it scrolls my UIcollectionView to top.

Now it's fourth month and still first module to go live.





Kotlin and Android studio


Kotlin is statically typed programming language. Google has announced kotlin an official language for android.
           Kotlin is getting popular among android developers around the globe. 
Starting from Android studio 3.0, Android studio will bring support for this  new language. So, You have nothing to do extra to play around with this new language.
If You are using android studio version smaller than 3.0, You have to go through some steps to make yourself  able to play around with Kotlin. follow the following steps.
1 . Open android studio.
2 . open settings and select plugins on left menu. It will open the plugins available.

3 . click on Browse repositories at the bottom of the list of     available plugins. It will open the following screen.

     Select Kotlin and Click on install button and  let it install.
4 . Restart Android studio.

Previous : Why Kotlin is good


Why kotlin is next programming language




Before discussing the cool features of Kotlin, We will discuss How Kotlin is good, because a study says programming language features  matter  little compared to the Ecosystem issues when developers evaluate a programming language.

Why Kotlin is good :
Kotlin compiles to JVM bytecode and JavaScript : It is of greatest  interest to people who use Java today, although it could appeal to people who use garbage collected at runtime,  including people who use Scala, Go, Python, Ruby and JavaScript.

Kotlin comes from Industry : 
Kotlin comes from industry not academia. It solves problems of working developers. For example type system helps you to avoid null pointer exceptions.

To adopt,  Kotlin costs nothing: 
 Kotlin is open source, but I don’t mean this at all. What I mean is, one click java to kotlin convertor tool, and a strong focus on java binary compatibility. You can convert  your existing java file to kotlin file on a single click, doesn’t matter how many lines of code this java file contains.

Kotlin programs can use all existing Java frameworks and libraries, even advanced frameworks that rely on annotation processing. The inter operation is seamless and does not require any wrapper or adapter layers. 

Kotlin is integrated with Maven, Gradle and other build systems.

Kotlin is very much like Scala, but simple. It can be learnt in few hours by reading language references. It is very much readable.
It enforces no particular programming philosophy , like overly functional and oop styling.


Kotlin is starting to become popular with Android developers.

Introduction to Kotlin


About:
Kotlin is a new programming language by JetBrains, the makers of the world’s best IDES. It  is a statically typed programming language that runs on the java virtual machine and can also be compiled  to  Javascript  source code. It’s primary development is from a team of JetBRains programmers based in Saint Petersberg, Russia.  The name came from Kotlin Island.


History :
In july 2011 JetBrains unveiled project Kotlin, a new programming language for JVM, which had been under development for a year. JetBrains lead Dmitry Jemerov said that most languages did not have the features they were looking for except Scala. However, he cited the slow compile time of scala as an obvious deficiency. One  of the stated  goals of Kotlin is to compile as quickly as Java. JetBrains open sourced the projct under Apache 2 license in 2012.
              JetBrains hopes that new programming language will drive IntelliJ IDEA sales.
Kotlin v1.0 was released on February 15,2016. This is considered as the first official stable release. In Google I/O 2017, Google announced first class support for Kotlin on Android.

Syntax :
Kotlin variable declarations and parameter lists have the data type after the variable name like Swift. Semicolon are optional.

Semantics :
In addition to the classes and methods(member functions) of object oriented programming, Kotlin also supports Procedural programming with use of functions. As in C and C++, the entry point to Kotlin program is a function named  “main”, which is passed an array containing any command line arguments. Perl and UNIX/LINUX shell script-style string interpolation supported and Type inference  is also supported.

Hello, World! Example
fun main(args: Array<String>){
val  scope=”world”
println(“Hello, $scope!”)
}
Kotlin makes a distinction between nullable and non-nullable datatypes. All nullable objects must be declared with “?” postfix after the type name. Operations on nullable objects need special care, null check must be performed before using the nullable value.
       Kotlin provides null-safe operators to help developers.
1 .  ?. (Safe navigation operator ) If the object is null method will not be called and the expression evaluates to null.
2 . ?:(null coalescing operator) often referred as Elvis operator

// Use of Elvis operator
fun wishGoodMorning(someNullableValue : String?, someNonNullableValue : Int){
val  name : String= someNullableValue ?:  “Stranger”
println(“Good morning $name”)
}
// Use of safe navigation operator
Foo  ?.   bar()  ?.    Baz()
//returns null if foois null, or bar() returns null, or baz() returns null
Tools :
1 . IntelliJ DEA has plugin support for Kotlin.
2 . JetBrains also provides a plugin for Eclipse.
3 . Integration with common Java build tools is supported including Apache Maven, Apache Ant and Gradle.             

                                                             Next : Why kotlin is good




Consider static factory methods instead of constructors




The normal way for a class to allow a client to obtain an instance of itself is to provide a public constructor. There is a technique that should be a part of every programmer toolkit. A class can provide public static factory method, which is simply a static method that returns an instance of the class.

Note – Static factory method is not the same as the factory method pattern from Design patterns.
A class can provide its clients with static factory method instead of, or in addition to constructors. Providing a static factory method instead of a public constructor has both advantages and disadvantages.

Advantages -

1 . Unlike constructors they have names.A static factory method with a well chosen name is easier to use and the resulting code easier to read. For example the constructor BigInteger(int, int, Random), which returns a BigInteger that is probably prime, would have been better expressed as a static factory method named as
BigInteger.probablePrime(int, int, Random)(This method was eventually added in the 1.4 release).
A class can have only a single constructor with a given signature.Programmers have been known to get around this restriction by providing two constructors whose parameter lists differ only in the order of their parameter types.This is real bad. User of such a API will never be able to remember which constructor is which and will end up calling the wrong one by mistake. People reading code that uses constructors will not know what the code does without referring to the class documentation.

2 . They are not required to create new instance each time they are invoked.This allows immutable classes to use preconstructed instances, or to cache instances as they're constructed and dispense them repeatedly to avoid creating unnecessary duplicate objects.
It can greatly improve performance if equivalent objects are requested frequently, especially if they are very expensive.
The ability of static factory methods to return the same object from repeated invocations allows classes to maintain strict control over what instances exist at any time. Classes that do this are called instance-controlled. Instance controlled class allows a class to guarantee that it is a singleton or non instantiable. Also it allows an immutable class to make guarantee that no two equal instances exist: object1.equals(object2) if and only if object1==object2. If a class makes this guarantee, then its clients can use the (==) operator instaed of calling equals, which may result in improved performance. Enum type provide this guarantee.

3 . Unlike constructors they can return an object of any subtype of their return type. This gives you great flexibility in choosing the class of returned type. This technique lends itself to interface-based frameworks , where interfaces provide natural return types for static factory methods. Using such a factory method requires the client to refer to the returned object by its interface rather than its implementation class, which is generally a good practice.
Example given below will explain above points.


// A service interface

public interface Service {
// methods go here
}
// A service provider interface

public interface Provider {
    Service newService();
}


// Non instantiable class for service registration and access

public class Services {
    private Services(){ }       // prevent creating instances
//Maps services names to services
    private static final Map<String,Provider> providers=new ConcurrentHashMap<String, Provider>();
    public static final String DEFAULT_PROVIDER_NAME = "def";
    //Provider registration API
    public static void registerDefualtProvider(Provider p){
        registerProvider(DEFAULT_PROVIDER_NAME,p);
    }
    public static void registerProvider(String name, Provider p){
        providers.put(name,p);
    }
//Service access API
    public static Service newInstance(){
        return newInstance(DEFAULT_PROVIDER_NAME);
    }
    public static Service newInstance(String name){
        Provider provider=providers.get(name);
        if(provider==null){
            throw new NullPointerException("No provider matching this name");
        }
return provider.newService();
    }
}
Disadvantages -

The main disadvantage of providing only static factory method is that classes without public or protected constructors can not be sub classed.
Second disadvantage of using static factory method is that they are not easily distinguishable from other static methods. They do not stand API documentation in the way that constructors do, so it can be difficult to figure out how to instantiate a class that provides static factory methods instead of constructors.




Supporting different languages and cultures in Android



Android app supports different languages and cultures. App includes resources that can be specific to a particular culture or locale. For example App can include locale specific string that can be translated to the language of current locale. It is always a good practice to keep culture specific resources.
     You can provide support for different locales by using resource directory. When culture specific resources are used, then resources corresponding to the current locale are loaded on run time.
Create locale specific resource files
create additional resource sub folders in res folder.
Each sub directory should have the following format
<resource type>-b+<language code>[+<country code>]
For example:
MyProject/
    res/
       values/
           strings.xml
       values-b+es/
           strings.xml
       mipmap/
           ic_country_flag.png
       mipmap-b+es+ES/
           ic_country_flag.png
For English locale(English is default locale)
values-es\strings.xml
<resources>
<string name="hello_world">Hello World</string>
</resources>
For Spainish locale
values-es\strings.xml
<resources>
<string name="hello_world">¡Hola Mundo</string>
</resources>
Use this resource in code
TextView txt_hello_world=(TextView)findViewById(R.id.txt_hello_world);
txt_hello_world.setText(getString(R.string.hello_world));
This string resource will be loaded on run time from the strings.xml file corresponding to current locale.
Same thing can be done for any type of resource like drawables etc.
For example locale specific mipmap directories contain locale specific country flag.
It will be used in layout files like this
<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@mipmap/ic_country_flag" />
When called from different locale then ic_country_flag.png is loaded from the mipmap folder corresponding to the current locale.

How to record screen in android using MediaProjectionManager


Starting from the Android lollipop there is a new api called MediaProjectionManager for recording mobile device screen video.
          In this session we will learn how it works in android.
First we get the MediaProjectionManager using getSystemService()(Available on any context)which provides the interface for Video recording permission intent and handling this intent creates MediaProjection instance. startActivityForResult() launches the permission intent and handled in onActivityResult().

First get the MediaProjetionManager instance.
private MediaProjectionManager mediaProjectionManager;
mediaProjectionManager = getSystemService(
    android.content.Context.MEDIA_PROJECTION_SERVICE);
Create the recording permission intent and show to the user
private static final int REQUEST_CODE_CAPTURE = 1000;
Intent recordingPermissionIntent = mediaProjectionManager.createScreenCaptureIntent();
startActivityForResult(recordingPermissionIntent, REQUEST_CODE_CAPTURE);
 This intent will be handled in Activity's onActivityResult() method
private MediaProjection mediaProjection;

public void onActivityResult(int requestCode, int resultCode, Intent intent) {

        if (resultCode == RESULT_OK) {
            mMediaProjection = mediaProjectionManager.getMediaProjection(resultCode, intent);

        } else {
            // user did not grant permissions
        }

}
Once the MediaProjection instance is available, We can create the virtual display and tell android on what surface you want to copy or record. First initialize the video encoder.
 
private static final String VIDEO_MIME_TYPE = "video/avc";
private static final int VIDEO_WIDTH = 1280;
private static final int VIDEO_HEIGHT = 720;
private Surface inputSurface;
private MediaCodec videoEncoder;
    MediaCodec.BufferInfo videoBufferInfo = new MediaCodec.BufferInfo();
        MediaFormat mediaFormat = MediaFormat.createVideoFormat(VIDEO_MIME_TYPE, VIDEO_WIDTH, VIDEO_HEIGHT);
        int frameRate = 30; // 30 fps

        // Set some required properties. The media codec may fail if these aren't defined.
        mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,
                MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
        mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 6000000); // 6Mbps
        mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
        mediaFormat.setInteger(MediaFormat.KEY_CAPTURE_RATE, frameRate);
        mediaFormat.setInteger(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER, 1000000 / frameRate);
        mediaFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
        mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1); // 1 seconds between I-frames

        // Create a MediaCodec encoder and configure it. Get a Surface we can use for recording into.
        try {
            videoEncoder = MediaCodec.createEncoderByType(VIDEO_MIME_TYPE);
            videoEncoder.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
            inputSurface = videoEncoder.createInputSurface();
            videoEncoder.start();
        } catch (IOException e) {
               e.printStackTrace();
            //RELEASE ENCODERS
        }
Once the encoder is set up MediaMuxer will be required which converts the inputs into the outputs. We can have multiple inputs (audio from mic, video from camera)in this case only one input, so, this is simple. Create a virtual display representing the dimensions of the screen specified and outputting the screen to the surface of the encoder we created.
private MediaMuxer mMuxer;
    try {
            mMuxer = new MediaMuxer("/sdcard/video.mp4", MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
        } catch (IOException ioe) {
            throw new RuntimeException("MediaMuxer creation failed", ioe);
        }

        // Get the display size and density.
        DisplayMetrics metrics = getResources().getDisplayMetrics();
        int screenWidth = metrics.widthPixels;
        int screenHeight = metrics.heightPixels;
        int screenDensity = metrics.densityDpi;

        // Start the video input.
        mediaProjection.createVirtualDisplay("Recording Display", screenWidth,
                screenHeight, screenDensity, 0 /* flags */, inputSurface,
                null /* callback */, null /* handler */);
 Now it's time to drain the encoder. It fetches an output buffer from the encoder and writes all the bytes to the muxer. This means that all the recently recorded video will be written to the file produced by the muxer. We use a handler with a ten millisecond delay to  call repeatedly until the resources are released.
private boolean mMuxerStarted = false;
private int mTrackIndex = -1;    
private final Handler mDrainHandler = new Handler(Looper.getMainLooper());
    private Runnable mDrainEncoderRunnable = new Runnable() {
        @Override
        public void run() {
            // DRAIN ENCODER
        }
    };
Drain encoder
    mDrainHandler.removeCallbacks(mDrainEncoderRunnable);
    while (true) {
        int bufferIndex = videoEncoder.dequeueOutputBuffer(videoBufferInfo, 0);

        if (bufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
            // nothing available yet
            break;
        } else if (bufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
            // should happen before receiving buffers, and should only happen once
            if (mTrackIndex >= 0) {
                throw new RuntimeException("format changed twice");
            }
            mTrackIndex = mMuxer.addTrack(videoEncoder.getOutputFormat());
            if (!mMuxerStarted && mTrackIndex >= 0) {
                mMuxer.start();
                mMuxerStarted = true;
            }
        } else if (bufferIndex < 0) {
            // not sure what's going on, ignore it
        } else {
            ByteBuffer encodedData = videoEncoder.getOutputBuffer(bufferIndex);
            if (encodedData == null) {
                throw new RuntimeException("couldn't fetch buffer at index " + bufferIndex);
            }

            if ((videoBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
                videoBufferInfo.size = 0;
            }

            if (videoBufferInfo.size != 0) {
                if (mMuxerStarted) {
                    encodedData.position(videoBufferInfo.offset);
                    encodedData.limit(videoBufferInfo.offset + videoBufferInfo.size);
                    mMuxer.writeSampleData(mTrackIndex, encodedData, videoBufferInfo);
                } else {
                    // muxer not started
                }
            }

            videoEncoder.releaseOutputBuffer(bufferIndex, false);

            if ((videoBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                break;
            }
        }
    }

    mDrainHandler.postDelayed(mDrainEncoderRunnable, 10);
When recording is finished release the encoder and other resources
mDrainHandler.removeCallbacks(mDrainEncoderRunnable);
    if (mMuxer != null) {
        if (mMuxerStarted) {
            mMuxer.stop();
        }
        mMuxer.release();
        mMuxer = null;
        mMuxerStarted = false;
    }
    if (videoEncoder != null) {
        videoEncoder.stop();
        videoEncoder.release();
        videoEncoder = null;
    }
    if (inputSurface != null) {
        inputSurface.release();
        inputSurface = null;
    }
    if (mediaProjection != null) {
        mediaProjection.stop();
        mediaProjection = null;
    }
    videoBufferInfo = null;
    mDrainEncoderRunnable = null;
    mTrackIndex = -1;
Never forget to give READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions.