Friday, December 30, 2016

Android MediaRecorder Start Failed - 19

If you have ever used Android MediaRecorder to record video or audio in your android application, you must have faced this error. Recently I had nightmare in using MediaRecorder in my android application. I think it's most unstable class in Android SDK and there is a different behavior in each device. In this blog I am going to explain more about this and possible resolution of this.

First lets see wha's the meaning of this error : Android MediaRecorder Start Failed - 19

There is no documentation on Android developer site about this error code but from my experience I found out that it's because of mis match in size of video preview frame and MediaRecorder video size and this error comes randomly in different devices. The best approach is to use CamCorder profile as mentioned on Android developer site.

CamcorderProfile profile =CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
mMediaRecorder.setProfile(profile);

When you use this most of the following default values are set in MediaRecorder from the selected profile.


  • OutputFormat
  • AudioEncoder
  • VideoEncoder
  • VideoSize
  • VideoFrameRate

But this does not work on all the devices as some the devices don't accept these default values hence MediaRecorder does not work and specifically due to VideoSize it gives error. So to solve this you should manually set all the values. Following settings works on almost all devices

int width = mCamera.getParameters().getPreviewSize().width;
int height = mCamera.getParameters().getPreviewSize().height;

mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
mMediaRecorder.setVideoSize(width, height);
mMediaRecorder.setVideoFrameRate(30);

However there are still some problem with it. When I tested in some high resolution devices. I got following width and height from getPreviewSize()

2048
1536

But MediaRecorder failed to start and when I checked error log I got error.

Unsupported Video Dimension 1920 X 1688

That means it changed the dimension by itself and ignored the width and height I set it in setVideoSize. So that means you can not depend on it. So what's the solution for this. Well the solution is find the optimal video size based on your preferred frame dimensions and available supported size in your device. Following is the function I used for it.

private Size getOptimalPreviewSize(List sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.2;
double targetRatio = (double) w / h;
if (sizes == null) {}
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
// Try to find an size match aspect ratio and size
for (Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
// Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}


List sizes = mCamera.getParameters().getSupportedPreviewSizes();
Camera.Size optimal = getOptimalPreviewSize(sizes, 640, 480);

if(optimal != null){
           
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
mMediaRecorder.setVideoSize(optimal.width, optimal.height);
mMediaRecorder.setVideoFrameRate(30);      

}else{

int width = mCamera.getParameters().getPreviewSize().width;
int height = mCamera.getParameters().getPreviewSize().height;

mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
mMediaRecorder.setVideoSize(width, height);
mMediaRecorder.setVideoFrameRate(30);      

}    

For me above solution worked on almost all devices, first we get optimal size from available supported sizes and if there is no supported sizes then we use default preview size.

PHP / MySql - Generate Big Reports from Big Data

Big data is a term that describes the large volume of data – both structured and unstructured – that inundates a business on a day-to-day basis. But it’s not the amount of data that’s important. It’s what organizations do with the data that matters. Big data as a service market to grow in near future. “Big Data” analysis is a hot and highly valuable skill now a days. For the big data analysis, an organization needs reports generated from it and to generate reports from big data we need some spacial tricks. In this blog I am going to explain some best practices to generate big reports from big data in PHP / MySql.

Challenges we face in managing Big Data with MySql


In MySql when we have big data we face certain performance issues. Most crucial issue is slow performance of MySql. When you have millions of rows in table and you want to search certain raws from it, it will take some time to get data and you need to improve in that. So in MySql there is a way to make faster data retrieval.

INDEXING


Yes, that 's right indexing solved my issue. There was a table in my database which has 100K records and executing query from it was taking lots of time as there was no indexing. So I created an index on columns which are used mostly for querying that table and after creating index query was working blazing fast.

If you are facing the same issue, better check your database queries and optimize it with indexing to make it faster.

Challenges we face in generating Big Reports with PHP


In PHP when we generate big reports it will surely take time and while working with PHP we have certain restrictions. For example, a PHP script can run for only certain time limits on any server and that limits can not be changed on most of server providers. So in case of generating big reports we surely need time as we have lots of data at backend and from it we are creating reports. So how to deal with it. 

Here is the one solution I always use. You can make use of scheduled cron job. Cron jobs run in background and there is no time restrictions with it so it can run for any amount of time and it can resources as much as possible. So get the reports parameters from the user and save it in database and schedule it for certain time.  For example user want to see day wise sales of products for a month. Save parameters like month in database have a scheduled cron job to read this data and start creating reports in background. Once the report is generated you can notify user about it so they can download it. Which this trick you can generated Big Reports from Big Data.




Thursday, December 29, 2016

Copy Files via SSH from Another Server FTP

Recently for one of my project our server was hacked and some files were deleted and corrupted with malwares. So we had to restore the old backups. We were using the contabo web server where we have separate backup server with 100 GB space which was accessible only through FTP from the SSH. So in this blog I am going to explain how you can copy files Copy Files via SSH from Another Server FTP.

Step 1: Login to SSH with your SSH username and password. 


ssh yourusername@host

On prompt of password enter password and login.



Step 2 : Go to directory where you want to copy files from FTP.


cd /yourpath/to/folder

Step 3: Connect to FTP


Use following command to connect to FTP

ftp hostname

It will ask for username and password. Once you enter correct username and password, you will get ftp command prompt.



Step 4 : Go to directory from where you want to copy files on FTP.


cd /yourpath/to/folder

You can use cd command on FTP just like you  use on SSH.

Step 5 : Copy Specific File.

Use following command to copy file.

get filename

And wait for the process to be finished.

Step 6 : Exit From FTP


Use following command to close FTP and return back to SSH.

bye

With this you will close the FTP session and you are back to SSH session and you can see the copied files using LS command.

Wednesday, December 28, 2016

Every Company Will be a Technology Company in 2017


Recently I was reading through some tech predictions of 2017 and one prediction caught my attention. It says.

Every Company Will be a Technology Company in 2017


It's very well said. Technology is growing and more and more businesses are adapting technology to grow. No matter what the business or company is, they are in need of more and more technical solutions to sustain in competition and grow the business. In 2011, Marc Andreesen famously wrote a Wall Street Journal essay declaring that “software is eating the world.” Five years later, the five largest companies in the world by market capitalization are all software companies. Today it doesn't matter what industry you are in, how large or small your company is, or where you company is located. Every single company today is a technology company. Whether you are a mining organization looking at automated trucks, a real estate firm deploying an internal social network, a warehouse looking to leverage wearable devices, an agricultural company exploring the internet of things, or a hospital interested in teaming up with IBM Watson, every single company today is a technology company and more companies will be technology company in 2017. 



Today in the era of technology people are becoming smart and at the same time they are becoming demanding in terms of services. You end users will expect and more and more services which can be easily available. They don't like to wait, it should be done immediately. They  want hassle free services. They don't want wait in queue on wait on phone call. If something can be done by sitting at home or through mobile phone, they will prefer it. Today in busy life nobody have time so everyone is looking for a solution and services that can save their time and money. So all the companies must have innovative technology solutions that can make their customer happy and for that they have to go for IT and technology solution. With technology solutions like Mobile Applications and Cloud based services it will be easy to server customer in real time and all the companies will be looking for such solution in 2017. If a company does not adopt technology solution, they may have to lose their customers in 2017. Every company in every industry, from agriculture, mining, and manufacturing to logistics, financial services, and healthcare, will become a technology company. Additionally, every technology company will need a CTO who has a deep understanding of the company’s technological infrastructure, software development, and support needs.



For companies to successfully make the transition and become a technology company, cultures need to change to take into account the unique way that software development works and to highlight the importance of technology and the people who manage and build it. They have to convince their customers about the technology they offer. We have seen certain example where a company wanted to become technology company and implemented IT solutions but it failed to convince customers to use it hence they failed to be technology company.  A company has to create technology driven culture within the company to be successful technology company. They have to hire and train staff to make them understand about technology. Companies need to move fast and adopt agile practices. The pace of technology adoption is getting faster and faster every year. For example, it took decades for electricity and telephones to reach 50% of US households, but today it takes only years for new technologies like smartphones and tablets to reach a majority of the population. To become a successful technology company, company has to invest in technology solutions and infrastructure with proper planning. They have to study market and hire consultants to give them proper directions and build a proper strategy of transformations. Off course this transformation will not be easy also it may end up in mess but a company has to do it. 

Conclusion


The race to become the market leader across a variety of sectors and geographies is speeding up so Every Company Will be a Technology Company in 2017

Saturday, December 24, 2016

Step By Step Guide on iOS TestFlight Beta Testing

In this blog I am going to explain step by step procedure of TestFlight Beta Testing in iOS.

What is TestFlight?




TestFlight was the platform built for iOS beta testing. As we know iOS does not allow any application to be installed our of App Store and earlier to test you have to sync Apps with iTunes and proper provisioning profiles which was hard for newbies and non technical users. So TestFlight made this process simple and built platform where you can do it easily with TestFlight app. Later on TestFlight was acquired by Apple and it was integrated in iTunes Connect. Still it sometimes confuses new user. So in this blog I am going to explain step by step procedure. 

Please note that you should have valid Apple Developer Account. If you don't have one please signup for it. 

Step 1 : Create Application Id

For this go to Apple Developer Member Center. Here is the Link Login here with Apple Developer Account credentials. Once you logged in following screen will be displayed. From here click on 

"Certificates, Identifiers & Profiles"


First of all we will create new Application Id. For that click on it Identifiers ---> App IDs and it will show you following screen. Click on + symbol on top right .


Once you click on + sign following form. Fill up information here as displayed below. Here you have to specify name of app and bundle ID and click on continue.



After continue, it will ask you to confirm it. Click on Register and your App id is created. Here your app id registration is completed. Click on Done. 

Step 2: Create Distribution Certificate and Distribution Provisioning Profile 

Next step is to create distribution certificate and provisioning profile as we need to sign application with it. 

First lets create Distribution Certificate. Click on Certificates ---> Production in the side menu. And then click on + icon on top right side.



It will start Add iOS certificate wizard. In first step. What type of certificate do you need? Select 

App Store and Ad Hoc below production and click on continue.  It will show you screen about creating certificate signing request. Create CSR file as mentioned here and save to your desktop and click on continue.

In the next step upload Certificate Signing Request you created and click on continue. In the final step it shows Your certificate is ready. Click on Done here.

Next we will create distribution provisioning profile. Click on Provisioning Profiles ---> Distribution and click + on top right side. 





It will start a wizard to create provisioning profile. 

In Step 1 What type of provisioning profile do you need? select Distribution ---> App Store and click on continue.

In Step 2 Select App ID, select App Id we created in Step 1 above and click on continue.


In Step 3: Select certificates, select the distribution certificate we created and click on continue.

In Step 4: Name this profile and generate. Give name of profile and click on continue.

In Step 5: Your provisioning profile is ready. Click on Done and your provisioning profile.


Step 3: Configure Xcode project and Generate Build

Next step is to configure Xcode project with provisioning profile and distribution certificate we created. Open your Xcode project. First we have to add your apple developer account in Xcode.

Go to Xcode ---> Preference ---> Accounts

Click on + sign and bottom and select Add Apple Id. It will ask for your credentials. Add  your email and password and Sign In.




Now select your project and in General tab select your Apple Developer Account.




It will download all the necessary profile and sing up your app. Now create an Archive to upload. First select Generic iOS device and then go to Product--->Archive




Now product is Archived.

Step 3: Create Application in iTunes Connect

we will upload it for the beta testing. Login to iTunes Connect with your apple development account credentials and click on My Apps. On the left side there is + sign. Click on that and choose New App. It will show following pop up, where you have to select the app and add necessary details.




This will create App. Now we will have to upload archive we created in Xcode. Go back to Xcode. Select the archive we created and Click on Upload to App Store.



It will prepare iPA file and shows you following dialog. Click on upload here. It will upload build to iTunes Connect.




Once the build is uploaded. It will take some in processing in iTunes connect. That you can select in activity screen. 

Once the build is processed, you have to submit it for beta review. For that go to TestFlight -> External Testing and click on select Add Build to Test.





Select the build you have submitted and add the necessary information on the screens which are prompted. Be specific to each information and give as much info as possible and submit for beta review. It will take couple of days to get it approved. Once approved. Add the external tester and click on Save. All the users will be notified with email and link to TestFlight app. 

Hope this helps you.

Friday, December 23, 2016

Cordova Text To Speech Plugin

Recently in one of our project we added Cordova Text To Speech using following plugin.

https://github.com/PluginCordova/cordova-plugin-tts

But during the development I faced certain issues so in this blog I am going to explain it.

1) It does not work in first attempt.

This plugin depends on Android Text to Speech class

https://developer.android.com/reference/android/speech/tts/TextToSpeech.html

And for that you need sample voice in the phone. If you are using this feature first time then first it will download sample voice from the android server. So let it get downloaded and then try it again.

2) Maximum Character Limit

There is limit of 32, 768 characters. If your string is bigger than this, it won't work. In this case split your text to smaller chunks and play it one by one like playlist.

3) It does not stop after start playing.

With the above plugin it does not stop playing. The reason is stop method is not implemented at all in this plugin.

So you have to make two changes for it.

First open tts.js file in plugins folder and exports.stop = function ()

There check for the following line.

cordova
.exec(function () {
if (promise) {
promise.resolve();
}
}, function (reason) {
}, 'TTS', 'stop');

Here the third param options is not passed so it will give JavaScript error. Change above code to.

cordova
.exec(function () {
if (promise) {
promise.resolve();
}
}, function (reason) {
}, 'TTS', 'stop',[]);

Now go to TTS.java file in src folder of your android project and look for the following method.

public boolean execute(String action, JSONArray args, CallbackContext callbackContext)

It does not have stop implementation.

Remove code of the function and use following code.

if (action.equals("speak")) {
speak(args, callbackContext);
} else if (action.equals("stop")){
Log.v("stop","stop speaking");
tts.stop();
}else{
return false;
}
return true;

That's it and it should work now.

Tuesday, December 20, 2016

Home Automation - Big Business Opportunity in 2017



Recently I read Facebook post of Mark Zuckerberg where he mentioned his personal challenge for 2016 was to build home automation. So he is working on Jarvis. You can read it at following link.

Building Jarvis


Well so if Facebook founder is working on Home automation that means there is really some interesting about it. Home automation is today a growing market globally, bringing new and exciting opportunities for technology companies. According to industry experts, the market will be driven by the trend towards energy efficient, safe, luxurious and convenient homes or smart homes. According to a report published by MarketsandMarkets, ‘APAC Smart Homes Market–By Products, Services and Geography – Analysis & Forecast (2013-2020),’ the total market for smart homes in the Asia Pacific region will be worth US$9.28 billion by 2020. With increasing availability of smart devices, wearable devices and connected devices, the demand of smart home is increasing. Consumers are really looking for automation in day to day activities in home and that creates big business opportunity in field of home automation.  Google also acquired Next lab. Nest Labs is a home automation producer of programmable, self-learning, sensor-driven, Wi-Fi-enabled thermostats, smoke detectors, and other security systems. This acquisition shows Google's interest in smart home sector. 

The growth factors of Home Automation


Vast availability of connected consumer electronics


Connectivity is rapidly becoming a reality with the development of smart technologies allowing devices to connect and talk with one another.  Your smart phone can connect with home appliances like security cameras, your LED tv, your refrigerator etc . This gives real boost to home automation as you can control everything from your smart phone. Also with increasing use of wearable devices, this is even becoming more easy to connect and communicate with other devices. With the innovation in technologies these devices are getting affordable. 

Increased Network Infrastructure


In metro cities you can easily find a open network anywhere. Also with increase in mobile networks and its speed, most of the users are now able to communicate from anywhere. This is still growing more and will boost home automation. You can control your home even if you are far away from it.

Increasing demand for new services in the home


Over the years, the evolving needs of home buyers have translated into a whole new set of consumer preferences and expectations from real estate developers. What was earlier considered luxury has now become the standard. Not to forget the rise of a financially powerful consumer class that demands a standard of living and luxury at par with the western world.


Challenges in Home Automation


Well, this is a growing market but there are still many challenges.

  • Cyber security concerns
  • Lack of interoperability
  • Unreliable performance of gadgets
  • Perfect Implementation of Artificial Intelligence

Monday, December 19, 2016

Cordova Upload PDF File

Recently in my project I created Hybrid application using Cordova. There was a requirement where we allow user to choose PDF file or any type of file and upload it to server.

So here are two parts, first let user choose file from SD card or phone memory or from iCloud drive on iOS.

Second part is to upload file to server with progress and store it and get it's path back in case if you want to show it some where. I will show example code on server side.

So lets first check the first part. For this we need following plugins. Please install it first.

https://github.com/jcesarmobile/FilePicker-Phonegap-iOS-Plugin This is specifically for iOS
https://github.com/don/cordova-filechooser This is specifically for Android
https://github.com/apache/cordova-plugin-file
https://github.com/apache/cordova-plugin-file-transfer

The file picker iOS plugin which I have mentioned here will not work for local photos and videos stored in camera roll. For this you have to make certain changes in the plugin. I have mentioned this in my previous blog. Please read it here.

http://davehiren.blogspot.com/2016/12/filepicker-cordova-ios-plugin-get-files.html

Now first lets invoke the plugin.

Android Example

fileChooser.open(function(obj) {
        var filePath = obj.path;
});

iOS Example

FilePicker.pickFile(function(obj) {
        obj = obj[0];
         var filePath = obj.path;
});

In both of this case we will get absolute path of files like

/path/of/file/filename.extension

Now we will have our logic to upload file to server using Cordova File Transfer plugin.

First of all we will get extension of file and keep it separate also we will have file name extracted from the path to send it to server.

var fileType = filePath.substring(obj.path.lastIndexOf('.'));

var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = filePath.substr(this.evidencePath.lastIndexOf('/') + 1);
options.mimeType = "text/plain";

var params = {};
params.fileType = type;
options.params = params;

var ft = new FileTransfer();

ft.onprogress = function(progressEvent) {
if (progressEvent.lengthComputable) {
//in case you want to show progress bar , your code goes here.
} else {
//loadingStatus.increment();
}
};

var win = function (r) {
        //success alert or your logic after successful upload
};

var fail = function (error) {
        //failure alert or your logic after successful upload
};

ft.upload(fileURI, encodeURI("http://pathtoyourserver"), win, fail, options);

So this was on JavaScript side. Now lets see on server side. I used PHP on server side so I will give you example of that. If you are using something else on server side, please implement your own logic.

$file_type = $_POST['fileType'];
$fileName = time()."_".$file_type;
move_uploaded_file($_FILES["file"]["tmp_name"], "/your/server/path/".$fileName);
return json_encode(array('success'=>true, 'server_path'=>'http://yourserverpath.com'.$fileName));

With this logic you can upload any type of file from your cordova app.

Objective C - Record Video With AVCaptureSession

Hello,

In this blog I am going to explain how to record video with AVCaptureSession in your iOS application.

First of all add following import statements in your view controller header file.

#import <Foundation/Foundation.h>
#import <CoreMedia/CoreMedia.h>
#import <AVFoundation/AVFoundation.h>
#import <AVKit/AVKit.h>
#import <AVFoundation/AVFoundation.h>
#import <AssetsLibrary/AssetsLibrary.h>

Now we will have to set preview layer for the recording in our view and also we will need input device and output file location. Also we need to add AVCaptureFileOutputRecordingDelegate to have notifications of events like recording stop.

Implement this delegate in your header file.

@interface MainViewController : CDVViewController
{
    BOOL WeAreRecording;
    BOOL ShareVideo;
    AVCaptureSession *CaptureSession;
    AVCaptureMovieFileOutput *MovieFileOutput;
    AVCaptureDeviceInput *VideoInputDevice;
}

Now we will set preview layer and init AVCaptureSession in viewDidLoad and set input and output.

CaptureSession = [[AVCaptureSession alloc] init];
AVCaptureDevice *VideoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDevice *audioCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
NSError *error = nil;
AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioCaptureDevice error:&error];
if (audioInput)
{
[CaptureSession addInput:audioInput];
}

[self setPreviewLayer:[[AVCaptureVideoPreviewLayer alloc] initWithSession:CaptureSession]];
PreviewLayer.orientation = AVCaptureVideoOrientationLandscapeRight;
[[self PreviewLayer] setVideoGravity:AVLayerVideoGravityResizeAspectFill];

Now we will setup output file and video recording settings and image quality.

MovieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
Float64 TotalSeconds = 60;
int32_t preferredTimeScale = 30;
CMTime maxDuration = CMTimeMakeWithSeconds(TotalSeconds, preferredTimeScale);
MovieFileOutput.maxRecordedDuration = maxDuration;
MovieFileOutput.minFreeDiskSpaceLimit = 1024 * 1024;
   
if ([CaptureSession canAddOutput:MovieFileOutput])
    [CaptureSession addOutput:MovieFileOutput];
   
[self CameraSetOutputProperties];

[CaptureSession setSessionPreset:AVCaptureSessionPresetMedium];
if ([CaptureSession canSetSessionPreset:AVCaptureSessionPreset640x480])
    [CaptureSession setSessionPreset:AVCaptureSessionPreset640x480];
   
CGRect layerRect = [[[self view] layer] bounds];
CGRect viewBoundsPreview = [self.webView bounds];
viewBoundsPreview.origin.y = 20;
viewBoundsPreview.size.height = viewBoundsPreview.size.height - 40;
[PreviewLayer setBounds:viewBoundsPreview];
[PreviewLayer setPosition:CGPointMake(CGRectGetMidX(layerRect),
 CGRectGetMidY(layerRect))];

UIView *CameraView = [[UIView alloc] init];
[[self view] addSubview:CameraView];
[self.view sendSubviewToBack:CameraView];
[[CameraView layer] addSublayer:PreviewLayer];
[CaptureSession startRunning];

Now capture session is running, we have to start and stop recording.

To start recording, add following code to your handler.

NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
NSNumber *timeStampObj = [NSNumber numberWithInteger:timeStamp];
NSString* fileName = [timeStampObj stringValue];
fileName = [fileName stringByAppendingString:@".mov"];
NSString *outputPath = [[NSString alloc] initWithFormat:@"%@%@", NSTemporaryDirectory(), fileName];
NSURL *outputURL = [[NSURL alloc] initFileURLWithPath:outputPath];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:outputPath])
{
NSError *error;
if ([fileManager removeItemAtPath:outputPath error:&error] == NO)
{
//Error - handle
}
}
//Start recording
[MovieFileOutput startRecordingToOutputFileURL:outputURL recordingDelegate:self];


Above code will start recording. Add following code to stop recording.

[MovieFileOutput stopRecording];

This will stop recording and save video to Photos library.

Friday, December 16, 2016

Objective C - Play Video From Application Temp Folder

Recently in one of my iOS project , there was requirement to play Video stored in temporary folder of Application data. After some hours of struggle I managed to get it working.

So the problem I was facing is I have absolute URL of the video that I was trying to play in MPMoviePlayerController but it was not working as the player was displayed for couple of seconds and it's dismissed automatically and there was a black screen.

So after sometime I found out that MPMoviePlayerController is deprecated, instead of it we shall use AVPlayer and that too was not working if I give absolute path to initialize a player. So first of all I just extracted file name fro the absolute path will following code.

NSRange range = [filePath rangeOfString:@"/" options:NSBackwardsSearch];
NSUInteger index = range.location;      
filename = [filePath substringFromIndex:index+1];

Now we will initialize player. Please note you have to import AVKIt first in your header file.

#import <AVKit/AVKit.h>

Now initialize player.

NSString *outputPath = [NSTemporaryDirectory() stringByAppendingPathComponent:filename];
AVAsset *asset = [AVAsset assetWithURL:[NSURL fileURLWithPath:outputPath]];
AVPlayer *_avPlayer = [[AVPlayer alloc]initWithPlayerItem:[[AVPlayerItem alloc]initWithAsset:asset]];

movieLayer = [AVPlayerLayer playerLayerWithPlayer:_avPlayer];
movieLayer.frame = self.view.bounds;
[self.view.layer addSublayer:movieLayer];

So player will be added as sublayer on the view so we have to dismiss it when video finished playing.

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(videoDidFinish:)
name:AVPlayerItemDidPlayToEndTimeNotification
  object:[_avPlayer currentItem]];

And add callback function to remove player layer.

- (void)videoDidFinish:(id)notification
{
    NSLog(@"finsihed");
    [movieLayer removeFromSuperlayer];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}


That's it. Hope this will help you.

FilePicker Cordova iOS Plugin - Get Files From Photos

Hello,

Recently in one of my iOS project we have requirement to let user browse and select files. So we needed FilePicker plugin for iOS. It should also allow user to browse through document providers like iCloud drive, Dropbox or Google drive.


So after searching for the plugin I found following plugin which works fine for iCloud drive.


https://github.com/jcesarmobile/FilePicker-Phonegap-iOS-Plugin


I would like to thank developer of above plugin as I just added more code to it to fulfill my requirement.

But my other requirements were not fulfilled to pick up photos and videos from saved photos album so I made some changes in this plugin. Here in this blog I will explain how to do this.

First of all install above plugin through command line and open your project in Xcode and open file

Plugins ==> FilePicker.h and Plugins ==> FilePicker.m

This plugin shows pop over menu with all available document providers so first we have to add option to browse photos and videos.

Open FilePicker.h file and add following import statement.

#import

And add following delegates.

@interface FilePicker : CDVPlugin

Now Open FilePicker.m file and find displayDocumentPicker and add following code to it.

[importMenu addOptionWithTitle:@"Photos & Videos" image:nil order:UIDocumentMenuOrderFirst handler:^{
        
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
imagePickerController.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:imagePickerController.sourceType];
imagePickerController.allowsEditing = NO;
imagePickerController.videoQuality = UIImagePickerControllerQualityTypeHigh;
imagePickerController.delegate = self;
[self.viewController presentViewController:imagePickerController animated:YES completion:nil];

}];


This will add menu and we set delegate to self so now we have to callback functions. Add following function in the file.

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
    if ([mediaType isEqualToString:@"public.image"]){
        NSData *imageData = UIImagePNGRepresentation((UIImage*) [info objectForKey:UIImagePickerControllerOriginalImage]);
        NSString* size = [NSString stringWithFormat:@"%li",  (unsigned long)[imageData length]];
        NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
        NSNumber *timeStampObj = [NSNumber numberWithInteger:timeStamp];
        NSString* fileName = [timeStampObj stringValue];
        
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *imagePath =[documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.png",fileName]];
        if (![imageData writeToFile:imagePath atomically:NO])
        {
            //send failure response;
            self.pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Failed to cache image data to disk"];
            [self.pluginResult setKeepCallbackAsBool:NO];
            [self.commandDelegate sendPluginResult:self.pluginResult callbackId:self.command.callbackId];
        }
        else
        {
            NSArray *arr = @[
                             @{@"path": imagePath, @"size": size}
                             ];
            
            self.pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:arr];
            [self.pluginResult setKeepCallbackAsBool:NO];
            [self.commandDelegate sendPluginResult:self.pluginResult callbackId:self.command.callbackId];
        }
    }
    else if ([mediaType isEqualToString:@"public.movie"]){
        NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
        NSString* path = [[videoURL absoluteString] substringFromIndex:7];
        NSData *data = [NSData dataWithContentsOfURL:videoURL];
        NSString* size = [NSString stringWithFormat:@"%li",  (unsigned long)[data length]];
        NSArray *arr = @[
                         @{@"path": path, @"size": size}
                         ];
        
        self.pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:arr];
        [self.pluginResult setKeepCallbackAsBool:NO];
        [self.commandDelegate sendPluginResult:self.pluginResult callbackId:self.command.callbackId];
    }
    [picker dismissViewControllerAnimated:YES completion:NULL];
}

So as you can see in above code we are checking if picked media is image, then first we have to move application temp storage as iOS does not allow you to access assets directly from photos so we are making a copy with following code.

NSData *imageData = UIImagePNGRepresentation((UIImage*) [info objectForKey:UIImagePickerControllerOriginalImage]);
NSString* size = [NSString stringWithFormat:@"%li",  (unsigned long)[imageData length]];
NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
NSNumber *timeStampObj = [NSNumber numberWithInteger:timeStamp];
NSString* fileName = [timeStampObj stringValue];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *imagePath =[documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.png",fileName]];
if (![imageData writeToFile:imagePath atomically:NO])
{
}
else
{
}


And for the videos we are sharing absolute URL to result callback. Also the plugin result is now array with path and size attribute. So we have to change the code of plugin to send same result for other document providers. Find out following function in FilePicker.m file.

- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url

And replace it with following function.

- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url {
    
    [url startAccessingSecurityScopedResource];
    __block NSData *pdfData = nil;
    
    NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] init];
    __block NSError *error;
    [coordinator coordinateReadingItemAtURL:url options:0 error:&error byAccessor:^(NSURL *newURL) {
        pdfData = [NSData dataWithContentsOfURL:newURL];
        NSString* size = [NSString stringWithFormat:@"%li",  (unsigned long)[pdfData length]];
        NSArray *arr = @[
                         @{@"path": [url path], @"size": size}
                         ];
        
        self.pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:arr];
        [self.pluginResult setKeepCallbackAsBool:NO];
        [self.commandDelegate sendPluginResult:self.pluginResult callbackId:self.command.callbackId];
    }];
    [url stopAccessingSecurityScopedResource];
    
}

So in JavaScript, following code should work.

FilePicker.pickFile(function(obj) {
alert(obj[0].path);
alert(obj[0].size);
}

Hope this helps you.

Thursday, December 15, 2016

Vehicle Tracking - GPS Units vs Smartphone Applications


As we know now a days vehicle tracking is being important for businesses and users.

All the businesses want to know 

  • Where their vehicles are?
  • How much they travelled?
  • What route they have taken?
  • Is it cost effective route?
  • How they can reduce fuel expenses?

All the end users want to know

  • When the item will be delivered?
  • What is the current status and where it reached?
  • How much more time will it take?
So most the business are looking for GPS based tracking system for their vehicles. Now it leads to a question that what is the effective tracking solution? 

A Standalone and embedded GPS unit or A Smartphone Application

This blog will clarify more on this and help you decide the best solution for you. 

First of all lets see what is Embedded GPS Unit.



GPS unit is device with it's own operating system, display and sender and receiver to track users. It can be in the small chip that can be installed in your vehicle and that can communicate with GPS satellite and your location to predefined receiver.

It can be simple device with display and some kind of configurable panel where user can interact with it and can change settings of it. In any case stand alone GPS units are specially designed devices with it's own chip sets and all. It has to be manufactured from scratch.

What is Smartphone Application



Now a days all smart phones like Android, iOS have capability of interacting with GPS satellites so based on this there are smart phone applications which can take advantage of GPS capability and can be used to track mobile locations. This smartphone application can be developed easily and can work with any type of servers and easy to maintain. Basically this application will work on background and will send location information for tracking.
Here are some vital comparisons on both approach. 

-->


GPS Units Smartphone Applications
Cost High No Cost to Moderate Cost
Accuracy High Moderate to High
Special Hardwares Mandatory Not required
Compatibility No Yes
Human Interference Not Possible Moderate
Maintenance Required Not Required

As you can see in above table GPS units are not cost effective as it needs special hardware and embedded system designs. However in case of mobile app your smartphone works as hardware. 

Accuracy is much higher in case of GPS units as it's built with spacial hardwares, while smart phone apps depends on phone hardware and in some devices it may not give accurate result.

Special hardware designs are required for GPS units which is not required in case of smart phone apps. Also GPS units designed with some hardware may not be compatible with other hardwares, which is not a case for smartphone apps. It works on almost all the platforms and all the devices.

Biggest advantage of stand alone GPS unit is almost no human interference, as this is the embedded systems so users can not hack or cheat with it. While smartphone apps can be hacked by user interface, For example, user can kill background services in phone or can switch off phone GPS etc. so user can not be tracked.

Tuesday, December 13, 2016

Add Mobility To Hiring Process and Go Paperless

It looks like mobility in hiring process is going to be emerging trends of HR industry and it will dominate in upcoming years.



The end-to-end recruitment process of a candidate is a tedious one. This further becomes a nightmare in mass recruitment scenarios. To find the right talent, HR departments have to manage interview schedules and gather documents, test scores and interviewer feedback for hundreds of applicants. Collating all this data for each applicant to make a well-informed hiring decision is often a manual and time-consuming process leading to high drop-outs and disengaged candidates.

To overcome this issue, organizations must add mobility to hiring process. Such integrations and delivery on mobile platforms are making the process paperless, convenient, error-free and efficient.

Here in this blog I am going to introduce one such innovate product designed by me and my team which offers solution to make joining process easy and hassle free and paper less.

Adsum Joining Module 

Adsum Joining Module is built for making joining process easy and smooth. With this module you can collect data of candidate in digital format, can send offer letter to them get back signed offer letter and do all the joining process which can is flexible and can be designed as per your organizations standards and policies.






Key Benefits And Features


  • Implement process as per your company process and standards.
  • Allow candidate to upload documents and data in digital format.
  • All the standard validations and security checks are applied.
  • Extensive backend to view uploaded documents and data from candidate.
  • Real time PUSH notifications to mobile app on accepting and rejection of documents and data.
  • Maintain history of complete hiring process both on backend and mobile app.
  • On the fly offer letter and appointment letter generation from template.
  • Create additional forms to fill up from the backend.
  • Secure Cloud storage for all the data and documents.

With this joining module, your hiring process will be much easy and hassle free as all the documents are maintained in digital format so you don't need to store documents physically so you can go paperless. With the web based backend and mobile app you can do joining process from any part of the world.

So get this solution for your business and increase your productivity and profit.

For further information, please contact.

Email : app@novustouch.com
Phone : Vibhay Vaidya : +919920465555 / Rinkal Shah : +919898171728





Monday, December 12, 2016

Update Magento 2 From 2.0.0 to 2.0.2

In this blog I am going to mention how to update Magento 2.0 from 2.0.0 to 2.0.2 This procedure you can follow for future updates as well.



There are two ways to do this. If you don't like to work with command line tools, then you can upgrade Magento from System Upgrade in admin.

Login to Magento Admin and Go to

System > Tools > Web Setup Wizard

Here there is an option "System Upgrade"


Select that option and follow through wizard. For more information check following link.



Other way to upgrade is with command lines which I like the most as it's just matter of typing some commands and your Magento is upgraded.

Go to terminal and go to your Magento root directory and run following commands.

composer require magento/product-community-edition 2.0.2 --no-update
composer update

This will update your Magento. After update do some clean up and indexing with following set of commands.

rm -rf var/di var/generation
php bin/magento cache:clean
php bin/magento cache:flush
php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento indexer:reindex

And you have updated Magento 2 version.

Saturday, December 10, 2016

Cordova Application Hanging During Startup on iOS 10

Hello,

If you have any cordova application in iTunes, you may have faced this issue since launch of iOS 10,. Either your app hangs at Start up or it will hang in case when there is a use of any plugin, like camera or location or any other native features. 

This is because of content security policy. iOS 10 needs content security policy where you have to mention what types of content you will allow to load.

As you have notice cordova plugins are invoked gap:// and in iOS 10 it's not allowed by default so you have to mention this in content security policy. 

Add following line in head section of your index.html file.

<meta http-equiv="Content-Security-Policy" content="media-src *; img-src * data:; font-src * data:; default-src  * gap:; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'">


As you can see we have added gap: in allowed content src along with other source, now your app will work normally in iOS 10.

Hope this helps you.

Friday, December 9, 2016

Digital Brochures For Builders, Real Estate Developers

World is going towards digitization but Real Estate Sector is still not using digital technology at it's best. They are still following the old approach of printed brochures to show their development informations and all. This is not just costing them much but this is no more a convenient way.

When I have a smart phone in my hand why should I carry printed, bulky brochure, that can be mis placed or won't be able to give me all the information I need. Instead of that if we have digital brochure, you can just have it in your smart phone. You can check it anytime, it does not consume much space and will be available anytime.


For the digital brochures, a mobile application is the best way to deliver. If you are in real estate business, then having mobile app for your projects will be one of the best way to market your projects and get more customers. A mobile application with all the features to showcase your project can boost your sales and customer engagements.

Mobile application can easily be downloaded and installed in phone. Your customer can find it and can see your projects. You can send notifications to customers for your upcoming projects. You can show entire gallery of your projects. You can show your project location on map, so customer can see exact location and app can guide them to reach at your project easily instead of manually finding a way.

I will give you more information by giving an example of the app we created for leading real estate developer of Gujarat.

Recently we created Digital Brochure Mobile Application for KP Sanghvi Infra for show casing their projects. I will give more informations about the features we added in the app. You can check application on Google Play Store


1) Show your projects according to category like Residential and Commercial



2) Show list of the projects according to selected category.



3) Let the user filter it based on project status and city



4) Show All the Information about selected project.


5) Show Project Gallery with filter like Floor Plan, 3D Photos etc, Since it's digital photographs, there is no limit.



6) Show Exact Project Location on Map and Guide user to come to your location easily.




So with this approach, your customer will have all your information in their. They can check and share it with others anytime. You can send notifications to customers. 

So go digital with this solution, if you need one contact us at.

Email : info@thedesignshop.co.in

Thursday, December 8, 2016

5 Simple Questions To Decide Hybrid vs Native Mobile App Development



If you’re confused and wondering whether to build a hybrid mobile app or a native mobile app, this article will help you decide the mobile app strategy.

Quick introduction to Hybrid and Native app

Hybrid App: Developer wraps web code (HTML / CSS / JavaScript) with native SDK. Can be easily deployed across multiple platform and is usually the cheaper and faster solution.

Native App: This is platform (iOS, Android etc.) specific and requires unique expertise. However the full potential of the platform can be leveraged which will drive great user experience and larger app capabilities (especially around phone hardware).

Following 5 simple questions will help you decide between Hybrid vs Native App Development.

1) Do you want to use Hardware and Native Features.

In your application if you want to use phone hardware like GPS, Camera, SD card etc, it's recommended to go for native app instead of hybrid app. Because native SDK has support to access hardware, For hybrid app depending on the framework, you may or may not hardware access. Also you have to consider performance as well. For example in one my project there was a requirement to get camera preview in the app and capture it. Initially I build hybrid app but camera preview was sluggish and slow so later I have to move to native app. If there is no requirement to access hardware then hybrid application is the best option.

2) Is the UI experience is more important in your application?

If you want to create an insane user experience, the native app approach would do better. A hybrid app can never match the level of user experience that you get in a native app. However, this doesn’t mean that the user experience of a hybrid app is bad. A good front-end developer in hybrid app can get close to a native experience. Also performance of native app is much better than hybrid app so when there is a high demand of performance, go for native app.

3) Does your app need background services?

If your application need to work in background like background location tracking, file download in background then native app is the best option as native SDK has classes to create background services that can be invoked by alarms etc. In hybrid app, if app is background or killed, all the process stops.

4) What is your Development Time and Budget?

If you have very limited budget and want to get app quickly to the market then hybrid app is the best option as you don't have to create separate application for each platform. One single code wrapped with multiple native wrappers will give you native application for different platform so it will save both time and cost. As for the single native app you have to hire native developers, while for hybrid app one developer is enough and it can be quickly developed and deployed to multiple platform.

5) Does your application need offline storage?

Most of the apps are built work offline and for this we need local database storage in app. If your application need more space for offline storage than native app is best option. However it's possible to have offline storage in hybrid app too. But there is a limitation up to certain MB. After that it does not allow more offline storage.


With these 5 questions you can define your development strategy.

Amazon RDS Connection Limit Exhausted

Recently in one of our project we built laravel application and deployed it on Amazon AWS and database was on Amazon RDS. In start there was no issue but after some months we had problems with database connection. After sometime laravel app could not connect to Amazon RDS.

So I checked RDS and dashboard and found out that number of database connection was beyond allowed limits. It means connection open to RDS was not closed after sometime and there were lots of half opened connections. That eventually crashing RDS sever and then connection was not established till we restart the RDS server.

So next step was to check database queries and find the queries which are taking time to execute and get data. After looking into all the queries I got the query which is taking long time to execute and that query was responsible half closed or non closed database connections and which is ultimately crashing Amazon RDS server.

So how I fixed that. Well we have a only one solution to speed up database queries and that is

INDEXING


Yes, that 's right indexing solved my issue. There was a table in my database which has 100K records and executing query from it was taking lots of time as there was no indexing. So I created an index on columns which are used mostly for querying that table and after creating index query was working blazing fast.

If you are facing the same issue, better check your database queries and optimize it with indexing to make it faster.

Wednesday, December 7, 2016

Top 3 Issues We Face With Sencha Touch Android Native App

As we all know using Sencha Touch and Cordova/Phonegap we can build native android application. Here in this blog I will mentioned top 3 issues we have to face while using Sencha Touch with Cordova and build native application. All three issues are related to Android Back Button event.



1) Android Back Button Press



Most of the android users are very much used to with android phone back button and Sencha Touch framework is very much user friendly with iOS. With Sencha Touch app on android, if you press back button of phone it exits the app instead of going back to previous screen. Because this back event is not properly handled by Sencha Touch framework. To solve this you have to bind Android back key press event with cordova and add your logic to go back to previous screen. I have mentioned this in my blog.

Please check Cordova Android Back Button Event

2) Hide Sencha Touch Pickers on Back Key Press



Ae we know sencha touch select field, date picker, action sheet shows picker to choose items from. Normally in android this types of pickers are dismissed when user press android back button. Button in case of sencha touch this types of pickers are nothing but floating panels and that does not hide on back key event. To solve this you have to bind Android back key press event with cordova and add your logic to go back to previous screen. I have mentioned this in my blog.

Please check Sencha Touch Hide Pickers On Android Back Key Press

3) Hide Sencha Touch Alert Box on Back Key Press



In Sencha Touch we have alert and confirm boxes. Normally in android this types of dialogs are dismissed when user press android back button. Button in case of sencha touch this types of alerts are nothing but floating panels and that does not hide on back key event. To solve this you have to bind Android back key press event with cordova and add your logic to go back to previous screen. I have mentioned this in my blog.

Please check Sencha Touch Hide Alert Box on Android Back Key Press