Sunday, September 30, 2018

Firebase Storage - How to attach timestamp to the pushed record?

Below is the code snippet for it

public class Member {
    private String name; //name of the member
    private String ID; //email for e.g
    private Map timestamp;
    private String fireBaseKey;

    public String getName(){return this.name;}
    public String getID(){return this.ID;}
    public Map getTimestamp() {return timestamp;}
    public String getFireBaseKey(){return this.fireBaseKey;}

    public void setName(String name){this.name = name;}
    public void setID(String ID){this.ID = ID;}
    public void setTimestamp(Map ts) {this.timestamp= ts;}
    public void setFireBaseKey(String key){this.fireBaseKey = key;}
}



Map map = new HashMap();
map.put("timestamp", ServerValue.TIMESTAMP);

Member member = new  Member();
member.setID(userID);
member.setName(name);
member.setTimestamp(ServerValue.TIMESTAMP);

DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference();
        String pathName = APP_NAME + "/" + conversation.getConversationPath();
        final DatabaseReference messagesRef = databaseReference.child(pathName).child(conversation.getFbRecordKey()).child("members");
        messagesRef.push().setValue(member);


Saturday, September 29, 2018

Javascript some quirks

the first one is for loop. In the below, the value idx is index into the array and not the object itself. coming from

for (idx in result){
    var obj = result[idx];
}

another surprise was the year from Date object

var sDate = startTimeField.getYear() +"-"+(startTimeField.getMonth()) +"-"+ startTimeField.getDate();

the output is 118-8-29, though expected outcome was 2018-9-29

Below code gives this result. getFullYear is different from getYear!

var sDate = startTimeField.getFullYear() +"-"+(startTimeField.getMonth()+1) +"-"+ startTimeField.getDate();


Thursday, September 27, 2018

What is cloudwatch?

Amazon CloudWatch monitors your Amazon Web Services (AWS) resources and the applications you run on AWS in real time. You can use CloudWatch to collect and track metrics, which are variables you can measure for your resources and applications. CloudWatch alarms send notifications or automatically make changes to the resources you are monitoring based on rules that you define. For example, you can monitor the CPU usage and disk reads and writes of your Amazon EC2 instances and then use this data to determine whether you should launch additional instances to handle increased load. You can also use this data to stop under-used instances to save money. In addition to monitoring the built-in metrics that come with AWS, you can monitor your own custom metrics. With CloudWatch, you gain system-wide visibility into resource utilization, application performance, and operational health.


Amazon CloudWatch console — https://console.aws.amazon.com/cloudwatch/
AWS CLI — For more information, see Getting Set Up with the AWS Command Line Interface in the AWS Command Line Interface User Guide.
CloudWatch API — For more information, see the Amazon CloudWatch API Reference.
AWS SDKs — For more information, see Tools for Amazon Web Services.


Below are the related services to the cloudwatch

Amazon Simple Notification Service (Amazon SNS) coordinates and manages the delivery or sending of messages to subscribing endpoints or clients. You use Amazon SNS with CloudWatch to send messages when an alarm threshold has been reached. For more information, see Set Up Amazon SNS Notifications.
Amazon EC2 Auto Scaling enables you to automatically launch or terminate Amazon EC2 instances based on user-defined policies, health status checks, and schedules. You can use a CloudWatch alarm with Amazon EC2 Auto Scaling to scale your EC2 instances based on demand. For more information, see Dynamic Scaling in the Amazon EC2 Auto Scaling User Guide.
AWS CloudTrail enables you to monitor the calls made to the Amazon CloudWatch API for your account, including calls made by the AWS Management Console, AWS CLI, and other services. When CloudTrail logging is turned on, CloudWatch writes log files to the Amazon S3 bucket that you specified when you configured CloudTrail. For more information, see Logging Amazon CloudWatch API Calls with AWS CloudTrail.
AWS Identity and Access Management (IAM) is a web service that helps you securely control access to AWS resources for your users. Use IAM to control who can use your AWS resources (authentication) and what resources they can use in which ways (authorization). For more information, see Authentication and Access Control for Amazon CloudWatch.

references
https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html

Wednesday, September 26, 2018

An Alternative to everymac - iPhone models

Interestingly when iPhone XS and XR released, i was trying to get the model number of these and was unable to get from everymac.com , the usual site idepend on. But there seems to be another site which is below

https://gist.github.com/adamawolf/3048717

The model properties are

iPhone11,4: iPhone XS Max
iPhone11,6: iPhone XS Max China

iPhone11,8: iPhone XR
iPhone11,2: iPhone XS                       

Tuesday, September 25, 2018

Opening Containing app from Today extension

self.extensionContext?.open(URL(string: "appscheme://")!, completionHandler: nil)

In the containing app, the scheme needs to be defined.

Also in the app delegate, below to be implemented as well

func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool
    {
        if url.scheme == "appscheme"
        {
// navigate to appropriate areas in the app.     
        }
        return true
    }

Even without having the above method implemented, it will launch the app. However, it won't be able to navigate to specific areas until the code is in place for it.

Implementation wise, one can just have the button on the today widget main interface.storyboard file and link it to the TodayViewController and handle the actions via IBaction outlets. It is pretty easy.

references:
https://hackernoon.com/app-extensions-and-today-extensions-widget-in-ios-10-e2d9fd9957a8

Today widget Content update life cycle

To help your widget look up to date, the system occasionally captures snapshots of your widget’s view. When the widget becomes visible again, the most recent snapshot is displayed until the system replaces it with a live version of the view.

widgetPerformUpdate :
called when widget is updated in background.
called before widget snapshot is taken.

func widgetPerformUpdate(completionHandler: @escaping (NCUpdateResult) -> Swift.Void)
    {
        completionHandler(.newData)
    }

references:
https://hackernoon.com/app-extensions-and-today-extensions-widget-in-ios-10-e2d9fd9957a8

Whats different in iOS 10 for Today Extensions?

In iOS 8 and iOS 9, Show More/Show Less needed to be handled explicitly by the developers. It was a tedious task since it required constraint and layout handling to adjust the widget’s height according to the content. But in iOS 10, Apple provided APIs to handle such functionality without taking much pain.

NCWidgetDisplayMode
There exist 2 modes in which you can display data in your widget. These modes are categorized under NCWidgetDisplayMode as compact and expanded.
Compact mode has a fixed height of 110 and
Expanded mode is used for variable height according to your content.
Show More or Show Less buttons are shown in the widget’s top right corner according to the widget’s active display mode i.e. in compact mode, show more is visible and in expanded mode, show less is visible.

override func viewDidLoad()
    {
        super.viewDidLoad()
        self.extensionContext?.widgetLargestAvailableDisplayMode = .expanded
    }

widgetLargestAvailableDisplayMode signifies the largest display mode supported by your app.
When set to compact, your app will only support compact mode i.e. show more/show less functionality will no longer be supported and your widget will have a fixed height of 110.
When set to expanded, the app will support both compact and expanded mode and show more/show less functionality will work accordingly.


Handling Height according to Display Mode
NCWidgetProviding protocol provides a delegate method widgetActiveDisplayModeDidChange(_: maxSize:) that handles the size of the widget in compact and expanded mode.
Width of the widget remains same according to the device you are using. There is no provision provided to change it.
Height of the widget can be changed according to the active display mode.

func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize)
    {
        if activeDisplayMode == .expanded
        {
            preferredContentSize = CGSize(width: 0.0, height: 220)
        }
        else
        {
            preferredContentSize = maxSize
        }
    }

references:
https://hackernoon.com/app-extensions-and-today-extensions-widget-in-ios-10-e2d9fd9957a8

How do we convert ISO date format to millis in Java?

The code is like below. Works perfect.

private void setTimestamp(String timeCreated) {
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
    try {
        Date timeCreatedDate = dateFormat.parse(timeCreated);
        timeStamp = (String) DateUtils.getRelativeTimeSpanString(timeCreatedDate.getTime(),
                                  System.currentTimeMillis(),
                                  DateUtils.SECONDS_IN_MILLIS);
    } catch ( ParseException e) {}
}

there are also one line solutions, but the above looks OK. Please note its Z in quotes. Else it gives parse exception.

references:
https://stackoverflow.com/questions/26519867/how-to-convert-iso8601-format-into-milliseconds?noredirect=1

Monday, September 24, 2018

Siri Relevant shortcuts

In addition to donating intents that the user has performed, apps can now share customisable relevant shortcuts for Siri to recommend at appropriate time in future This means that app can attach information about when or where this action might be useful to recommend. For e.g. app can recommend this shortcut should be recommended when at the gym or at home or during the morning or evening.

There are below 3 steps involved in this

1. Create instance of INRelevantShortcut object with INShortcut Instance
2. The use the relevanceProviders property to assign an array of INRelevanceProvider values
3. Get the INRelevanceStore and call setRelevantShortcuts to make Siri aware of the actions that the app can perform.


References:
https://willowtreeapps.com/ideas/wwdc-how-to-implement-siri-shortcuts-for-your-app

Donating Intents

Dontation is a means for an app to enable Siri to make a suggestion in the future for an action that user just performed.
Siri will look for patterns in a user's Donated intents and will periodically provide a relevant suggestion. By defining different parameter combinations for a custom intent, Siri is able to look at trends in those donated intents and corresponding combinations to make a good suggestion. It is also equally important to remove the intent if a certain piece of data is removed from the system.


References:
https://willowtreeapps.com/ideas/wwdc-how-to-implement-siri-shortcuts-for-your-app

What Are Siri Shortcut phrases

Apps now have ability to prompt the user to define a custom invocation string for a specific shortcut. This allows user to be app action into users own vocabulary. To do this, INUIAddVoiceShortcutViewController to prompt user for a custom shortcut statement. This view controller Takes an INShortcut object that represents the shortcut to be configured. Once the user configure the shortcut with a custom statement, they can view it in MyShortcuts in the settings app under Siri


Reference:
https://willowtreeapps.com/ideas/wwdc-how-to-implement-siri-shortcuts-for-your-app

iOS Custom Intents

Custom Intents now allow apps to define their own models for requests and responses to Siri that are specific to actions performed in the app. Now these actions aren’t constrained by Apple’s system domain of intents.

1. First task is to create an Intents extension
2. When creating an intents extension, it also create an Intents UI extension where a view controller can be defined. This view controller will be shown by Siri as embedded view controller when Siri is processing the intent
3. Third step is to create a new Siri intents definition file. Which was not previously possible because Apple only allowed to have predefined domain of shortcuts This file will help to define model of the apps's custom intent.


The two parts of Siri's custom intent

1.Define the params that the user will provide to Siri
2. Define how the Siri should respond to the intent after handling the request

When we create a new intent model, it will generate a couple of files, for e.g. if the intent was for presence check of a person, the classes may be created are PresenceCheckIntent and PresenceCheckIntentProtocol


What next to be done is, in the App's extension class, implement the protocol and provide appropriate handling. The two main functions to override are

confirm
and handle


References:
https://willowtreeapps.com/ideas/wwdc-how-to-implement-siri-shortcuts-for-your-app

Sunday, September 23, 2018

What is ADSL ?

ADSL is common type of DSL line that offers download speeds many times higher than upload speeds. This is the most common type of DSL used in residential applications. SDSL is usually more expensive type of DSL that offers upload speeds almost identical as download speeds.

ADSL works by using the frequency spectrum above the band used by voice telephone calls. With a DSL filter, often called splitter, the frequency bands are isolated, permitting a single telephone line to be used for both ADSL service and telephone calls at the same time.


ADSL WiFi AC Routers are designed to work only on an ADSL Broadband connection. (via a telephone line) An ADSL WiFi AC Router, also known as a WiFi 802.11ac Router or WiFi 5G Router, is the 5th generation of Gigabit Wi-Fi Routers and is the fastest, most reliable Wi-Fi standard for consumers and enterprises.

Also known as your Home or Business Broadband. It uses your existing telephone line into your house or office. ADSL is a type of Broadband Internet connection

A symmetric digital subscriber line (SDSL) is a digital subscriber line (DSL) that transmits digital data over the copper wires of the telephone network, where the bandwidth in the downstream direction, from the network to the subscriber, is identical to the bandwidth in the upstream direction, from the subscriber to

Symmetrical high-speed digital subscriber line (SHDSL) is a form of symmetric digital subscriber line (SDSL), a data communications technology for equal transmit and receive (i.e. symmetric) data rate over copper telephone lines, faster than a conventional voiceband modem can provide.

While ADSL provides speeds of 'up to 8Mbps', ADSL2+ is capable of delivering speeds of 'up to 24Mbps'. Furthermore, while ADSL provides a maximum upstream speed of 448Kbps (832Kbps in the case of ADSL MAX Premium), ADSL2+ allows an uncapped upstream experience, potentially up to 1.4Mbps.

VDSL is full line speed both ways, and is around 5x faster than ADSL for downloads, and approximately 10 x faster for uploads than ADSL. VDSL can reach speeds of more than 50 Mbps downstream, and 10 Mbps upstream.

The biggest difference between them is the improved maximum speed that you can get with ADSL2, which can reach up to 12Mbps while ADSL can only reach 8Mbps. ... This second upgrade to ADSL provides much faster speeds compared to both ADSL and ADSL2.


references:
https://www.google.com/search?q=whats+my+network+speed+&ie=utf-8&oe=utf-8&client=firefox-b-ab

Siri shortcut use cases

The link in references shows some of the apps in app store that has been updated to provide siri support. 

The Sky guide has a Cool option

This is a particularly cool option. After setting up a shortcut, you can point iPhone at the sky and ask Siri what star is that and she will identify it for you.

Master Job search also has a cool thing to save the Siri shortcuts can be used to save a favorite search so they don't have to type the query inside of Monster each time.

PCalc has a good one too, it allows to add shortcuts to Convert X from inches to centimetres.

References:
https://appleinsider.com/articles/18/09/17/how-your-favorite-apps-are-embracing-siri-shortcuts



Saturday, September 22, 2018

How to make a node js app work with sails js?

A node JS app that essentially has @require flags to define and load dependencies.
Sails JS is a framework built on top of Node JS. The dependencies are defined in package.json and the same package names defined in Sails JS can be pulled into the package.json of sails and place the html files in the view folder and thats it pretty much. before running, do an npm install, so that the dependencies are installed.

Enrolling for iOS developer program

there are 3 types of iOS developer program

1. iOS Developer program (99$ per year)
2. iOS Enterprise Developer program (299$ per year)
3. iOS University Developer program (Free)

iOS Developer program enables a developer to distribute apps on app store. Extend the ability to generate revenue from a developer's app on the app store with in-app purchase, iAd rich media ads, volume purchases and more.

there are mainly two enrollment types

1. Individual: this is if individual or sole proprietor or owner of business
2. company/organization: if it is a company, non profit organization, joint venture, partnership or government organization

Need to provide basic information about the enity who is enrolling. if its an organization, then the D-N-
U number etc. 

Typical Configurations in a Hotspot Redirector.

ZoneDirector is typical implementation of how a Redirector works. This redirector works with RADIUS, Web portal etc. Below are requirements for implementations such as ZoneDirector. 

- External Web server (such as Apache, IIS, or equivalent) with properly configured login portal page. 
- Local Directory, Active Directory, LDAP or RADIUS authentication server (RADIUS is preferred by many) 
- An Accounting server such as RADIUS 

Below are typical setup process in a Redirector

- Configure the AAA server. If we have selected RADIUS, we need to provide this here
- Configure the Accounting server, This is optional, required only if the operator is interested in knowing the details of the upload / download and other parameters 
- Configure a Hotspot with its name, Login page url ( the login url will be used to redirect unauthenticated users. This url will be added to the walled garden by the redirector automatically), a Start page (Page which is used for redirecting after the authentication is successful.) Session timeout (IF specified, the users will be automatically signed out when the session time elapsed. Sometimes RADIUS server also can specify the session timeout, if this is the case, this will be the value of the timeout.), Idle timeout, 

How does the Android build system find the dependancies?

I met with this error
Could not resolve all files for configuration ':app:debugRuntimeClasspath'.
> Could not find com.google.firebase:firebase-core:11.8.1

It claimed to say that it looked in the folder file:/Users/bond/Library/Android/sdk/extras/m2repository/com/google/firebase/firebase-core/11.8.1/
and manually navigating to this folder yes, I could not see the firebase stuff.

I checked the SDK location base path in the project structure dialog under SDK location, and the base path is same as the
one shown in the error where system tried to look for firebase.

/Users/bond/Library/Android/sdk

Also, another project in the same system for the same version is not giving this error and I remember earlier 11.8 compiled.

when i checked, the build.gradle has below,

compile 'com.google.firebase:firebase-core:11.8.1'
    compile 'com.google.firebase:firebase-messaging:11.8.0'
    compile 'com.google.android.gms:play-services:11.8.0'


and changed to implementation like below which actually seems to have resolved issue with app but the module still gives the error

Error:(29, 20) Failed to resolve: com.google.firebase:firebase-core:11.8.1
Show in File
Show in Project Structure dialog

One blog post was suggesting to do this, which i already had.

allprojects {
  repositories {
    // ...
    maven { url "https://maven.google.com" }
  }
}




Error:Could not resolve all files for configuration ':app:debugRuntimeClasspath'.
> Could not find com.google.firebase:firebase-core:11.8.1.
  Searched in the following locations:
      file:/Users/bond/Library/Android/sdk/extras/m2repository/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.pom
      file:/Users/bond/Library/Android/sdk/extras/m2repository/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.jar
      file:/Users/bond/Library/Android/sdk/extras/google/m2repository/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.pom
      file:/Users/bond/Library/Android/sdk/extras/google/m2repository/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.jar
      file:/Users/bond/Library/Android/sdk/extras/android/m2repository/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.pom
      file:/Users/bond/Library/Android/sdk/extras/android/m2repository/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.jar
      file:/Applications/Android Studio.app/Contents/gradle/m2repository/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.pom
      file:/Applications/Android Studio.app/Contents/gradle/m2repository/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.jar
      https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.pom
      https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.jar
      https://jcenter.bintray.com/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.pom
      https://jcenter.bintray.com/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.jar
      https://maven.google.com/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.pom
      https://maven.google.com/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.jar
      https://jitpack.io/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.pom
      https://jitpack.io/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.jar
  Required by:
      project :app
> Could not find com.google.firebase:firebase-core:11.8.1.
  Searched in the following locations:
      file:/Users/bond/Library/Android/sdk/extras/m2repository/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.pom
      file:/Users/bond/Library/Android/sdk/extras/m2repository/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.jar
      file:/Users/bond/Library/Android/sdk/extras/google/m2repository/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.pom
      file:/Users/bond/Library/Android/sdk/extras/google/m2repository/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.jar
      file:/Users/bond/Library/Android/sdk/extras/android/m2repository/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.pom
      file:/Users/bond/Library/Android/sdk/extras/android/m2repository/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.jar
      file:/Applications/Android Studio.app/Contents/gradle/m2repository/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.pom
      file:/Applications/Android Studio.app/Contents/gradle/m2repository/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.jar
      https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.pom
      https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.jar
      https://jcenter.bintray.com/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.pom
      https://jcenter.bintray.com/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.jar
      https://maven.google.com/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.pom
      https://maven.google.com/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.jar
      https://jitpack.io/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.pom
      https://jitpack.io/com/google/firebase/firebase-core/11.8.1/firebase-core-11.8.1.jar
  Required by:
      project :app > project :appynotifications

AMR WB Codec interface format

Each AMR-WB codec mode follows the generic frame structure depicted in figure 1. The frame is divided into three
parts: AMR-WB Header, AMR-WB Auxiliary Information, and AMR-WB Core Frame. The AMR-WB Header part
includes the Frame Type and the Frame Quality Indicator fields. The AMR-WB auxiliary information part includes the
Mode Indication, Mode Request, and Codec CRC fields.  The AMR-WB Core Frame part consists of the speech
parameter bits or, in case of a comfort noise frame, the comfort noise parameter bits. In case of a comfort noise frame,
the comfort noise parameters replace Class A bits of AMR-WB Core Frame while Class B and C bits are omitted.


references:
https://www.etsi.org/deliver/etsi_ts/126200_126299/126201/05.00.00_60/ts_126201v050000p.pdf

Thursday, September 20, 2018

Flutter Gesture handling


Gestures include tab, dragging, scaling. Gesture handling has two layers, first one is raw pointer event infos. Second layer is the actual gesture, which describe the semantic actions that consists of one or more pointer events.

Pointers represent raw data about the user’s interaction with the device’s screen. There are four types of pointer events:

    PointerDownEvent The pointer has contacted the screen at a particular location.
    PointerMoveEvent The pointer has moved from one location on the screen to another.
    PointerUpEvent The pointer has stopped contacting the screen.
    PointerCancelEvent Input from this pointer is no longer directed towards this app.


Gestures

Gestures represent semantic actions (e.g., tap, drag, and scale) that are recognized from multiple individual pointer events, potentially even multiple individual pointers. Gestures can dispatch multiple events, corresponding to the lifecycle of the gesture (e.g., drag start, drag update, and drag end):

    Tap
        onTapDown A pointer that might cause a tap has contacted the screen at a particular location.
        onTapUp A pointer that will trigger a tap has stopped contacting the screen at a particular location.
        onTap A tap has occurred.
        onTapCancel The pointer that previously triggered the onTapDown will not end up causing a tap.
    Double tap
        onDoubleTap The user has tapped the screen at the same location twice in quick succession.
    Long press
        onLongPress A pointer has remained in contact with the screen at the same location for a long period of time.
    Vertical drag
        onVerticalDragStart A pointer has contacted the screen and might begin to move vertically.
        onVerticalDragUpdate A pointer that is in contact with the screen and moving vertically has moved in the vertical direction.
        onVerticalDragEnd A pointer that was previously in contact with the screen and moving vertically is no longer in contact with the screen and was moving at a specific velocity when it stopped contacting the screen.
    Horizontal drag
        onHorizontalDragStart A pointer has contacted the screen and might begin to move horizontally.
        onHorizontalDragUpdate A pointer that is in contact with the screen and moving horizontally has moved in the horizontal direction.
        onHorizontalDragEnd A pointer that was previously in contact with the screen and moving horizontally is no longer in contact with the screen and was moving at a specific velocity when it stopped contacting the screen.

To listen to gestures from the widgets layer, use a GestureDetector.

class MyButton extends StatelessWidget {
@override
Widget build(BuildContext context){
    return GestureDetector(
        onTap:(){
            print("Button tapped");
        },
        child:Container {
            height:36.0,
            padding: const EdgeInsets.all(8.0),
            margin: const EdgeInsets.symmetric(horizontal:8.0)
'            decoration: BoxDecoration(
                borderRadius : BorderRadius.circular(5.0),
                color : Colors.lightGreen[500],
               
            )
        }
       
    )
}
}


References
https://flutter.io/gestures/

Tuesday, September 18, 2018

What the Heck? starting nginx gives duplicate entry and fails to start

Below was the error that is spit by the nginx


nginx: [emerg] duplicate location "/ms" in /etc/nginx/sites-enabled/':56

The reason is that while editing the default file, the vi editor seemed to have created a copy of the file and saved in an unstable state. the name was ' .. to remove this file, had to do the below 

sudo rm -rf \' 

then starting the server did the trick, 

the link in reference section contains the similar issue. 

references
https://www.digitalocean.com/community/questions/nginx-config-error-emerg-1226-0-duplicate-location 

iOS Siri Shortcuts - Basics

With shortcuts, users can access features of your app from places such as Spotlight search, Lock Screen, and the Siri watch face. With phrases, users can speak to Siri to access your app’s features.

Application can provide custom intent on a set of categories. This is done by adding an intent definition file to the project. A custom intent can define a set of parameters to accept and it can also define a type of response. Custom intent can also be marked for background execution. To use the details given in the custom intent definition file, app needs to define intent code.

To use custom intent in the app, Xcode need to generate the source code for the items defined inthe intent definition file. However, apps having the shared framework, the code generation should happen only for the shared framework, To specify which target has the generated source code, use the Intent Classes setting in the Target Membership panel. all other targets use the No Generated Classes setting.

Before Siri can suggest shortcuts to the user, the app must tell Siri about the shortcuts through intent donations.

private func donateInteraction(for order:Order) {
   let interaction = INInteraction(intent:order.intent, response:nil)
   interaction.identifier = order.identifier.uuidString
  
   interaction.donate { (error) in
       if (error == nil) {
        //no error. Interaction donation is successful. Great
    }
   }
}

The identifier can be used to cancel the intent if the user cancels the order.

Next task is to Handle the shortcut. Inorder to handle the shortcut, app provides an app extension, which handles the intent in background. When the app must be launched to handle the intent, the app is launched by the App Delegate call back below

override func restoreUserActivityState(_ activity : NSUSErActivity) {
    if(activity.activityType == NSUSerActivity.orderCompleteActivityType) {
       // this is order complete activity.
    }
}

All of the above was just about shortcut that appear in different places. How about if we could add a voice command to it? This can be done by adding custom voice phrases. This can be done by going to the app settings or even from the app following the below

Let addButton = INUIAddVoiceShortcutButton(style:.whiteoutline)
addShortcutButton.shortcut = INShortcut(intent:order.intent)
addShorcutButton.delegate = self





references:
https://developer.apple.com/documentation/sirikit/soup_chef_accelerating_app_interactions_with_shortcuts



How to do 'npm start' with pm2?

Below is the command to do this


pm2 --name "ms-stage" start npm -- start

by providing the --name , it appears in the list of pm2 items neatly.

references:

Why Does Xcode 10 complain libstdc++ is not present?

the libstdc++was deprecated quite sometime back. Instead, one should be using libc++ from the build phases. The problem is when there is a library that uses this framework. In that case, should get an updated library that uses the libc++.

A detailed discussion around this can be found at the link given in the references

references:
https://forums.developer.apple.com/thread/103732

Saturday, September 15, 2018

What is IRSF (International Revenue Sharing Fraud)






references:
https://www.slideshare.net/JeanMarieGandois/understanding-irsf-fraud-english

What is DSCP?

If possible, one should also take advantage of the DSCP support . DSCP, or Differentiated Services Code Point allows packets to be tagged to prioritize them on the network. Browsers that support DSCP are capable of tagging call media packets sent by the Client in this manner. Your router or network element can then use these tags to prioritize call media packets over other traffic on the network. Also, note that your router or network element needs to also be DSCP-compliant. DSCP is currently supported only by Google Chrome currently, and setting DSCP on Windows machines does not currently work. 

Friday, September 14, 2018

The Flutter Widget Framework

The minimal flutter app looks like the below
Import package:flutter/material.dart

void main(){
   runApp(
       Center (child:Text("Hello world",textDirection:TextDirection.ltr)
        )
    )
}


The runApp take given widget and makes it as the root of the widget. The framework forces the root widget to cover the screen in which case Center which is a widget is converting the entire screen.

When writing the app, one will commonly author new widget by subclassing either Stateless Widget or Stateful widget. A widget's main job is to implement a build function which describes the widget in terms of other, lower-level widgets.

References:
https://flutter.io/widgets-intro/

Wednesday, September 12, 2018

iOS Framework, how to load an image

Loading an image from the framework bundle does not work in below way

UIImage.init(named:"imagename")

this is because the reference to the bundle is going to be the main bundle and the image may be not in the xcassets  of the main bundle, instead it may be only in the bundle of the framework. Below to be used for loading image in a bundle

let icon = UIImage.init(named: "back", in: Bundle(for: A2ChatVC.self),compatibleWith: nil)?.withRenderingMode(.alwaysOriginal)

Monday, September 10, 2018

Does Android studio show all class names in Red?

Even though the project builds successfully, all of the class names if shows up in red, just do

File -> Invalidate Cache / Restart

Pretty useful and avoids the annoying look of red!


Firebase GoogleServices-Info.plist how to add?

Many times have gotten into the crash scenario due to the file was not added properly. Below is the common error.

*** Terminating app due to uncaught exception 'com.firebase.core', reason: '[FIRApp configure]; (FirebaseApp.configure() in Swift) could not find a valid GoogleService-Info.plist in your project. Please download one from https://console.firebase.google.com/.'

To avoid, it add like below 


How to load view View controller from storyboard inside an iOS framework?

        let podBundle = Bundle(for: FrameworkViewController.self)
        let storyboard = UIStoryboard(name: "Storyboard", bundle: podBundle)
        let vc = storyboard.instantiateInitialViewController()!
        parentController.present(vc, animated: true, completion: nil)


important point is to get the bundle object for the bundle which is holding the storyboard and the class essentially. 

What are the libraries usually required for VoIP SDK integration?


Once you've downloaded and unpacked the framework, navigate to your Xcode project's General settings page. Drag and drop VoIPSDK.framework onto the Embedded Binaries section. Ensure that "Copy items if needed" is checked and press Finish. This will add VoIPSDK.framework to both the Embedded Binaries and Linked Frameworks and Libraries sections.

Next, you will need to open your project's Linked Frameworks and Libraries configuration. You should see the VoIPSDK.framework there already. Add the following frameworks to that list:

AudioToolbox.framework
VideoToolbox.framework
AVFoundation.framework
CoreTelephony.framework
GLKit.framework
CoreMedia.framework
SystemConfiguration.framework
libc++.tbd
In your Build Settings, you will also need to modify "Other Linker Flags" to include -ObjC.

Before distributing your app to the  App Store, you will need to strip the simulator binaries from the embedded framework. Navigate to your target's Build Phases screen and create a new "Run Script Phase". Ensure that this new run script phase is after the Embed Frameworks phase. Paste the following command in the script text field:

/bin/bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/VoIPSDK.framework/remove_archs"

Background Modes

To allow a connection to a Room to be persisted while an application is running in the background, you must select the Audio, AirPlay, and Picture in Picture background mode from the Capabilities project settings page.

How to install same pod in multiple target?

Solution is simple, and below is possible because pod file is just a ruby file.

platform :ios, '9.0'

use_frameworks!

# My other pods

def common_pods
    pod 'Pod1', '0.5.0'
    pod 'Pod2', '2.0.0-rc.1'
end

target 'MyTarget1' do
    common_pods
end

target 'MyTarget2' do
    common_pods
end


references:
https://www.natashatherobot.com/cocoapods-installing-same-pod-multiple-targets/

What is an iOS bundle?

A Bundle (or NSBundle with Objective-C) is just a collection of resources. When you create an iOS application you start out with a main bundle (the contents of the .app file). When you create a framework Xcode stores the resources for that framework in a separate bundle (the file AmazingFramework.framework in this case).

To get the main bundle for an application:

// Swift
let mainBundle = Bundle.main

// Objective-C
NSBundle *mainBundle = [NSBundle mainBundle];
You can get the bundle that contains a class using init(for aClass: AnyClass). For the framework bundle that contains our AmazingView:

let amazingBundle = Bundle(for: AmazingView.self)

references:
https://useyourloaf.com/blog/loading-resources-from-a-framework/