Sunday, January 31, 2016

iOS 9.0 Launching Youtube, Facebook URLs

Interestingly, after updating the build to use Xcode 9.0 the Youtube launch URLs were giving issues that it wont open. Looking at the logs, it was giving the below error traces.

 -canOpenURL: failed for URL: "youtube://www.youtube.com/watch?v=Ere-FvKExXY&index=3&list=PLtZjA7gksgZS74bJl5NJbns2-bP6Jk-hJ" - error: "This app is not allowed to query for scheme youtube"

I do not remember seeing somewhere this is documented when going through the iOS 9.x related changes. Below seems to be what is required to fix the issue. We need to add property in the LSApplicationQueriesSchemes like shown in image below

References:
http://useyourloaf.com/blog/querying-url-schemes-with-canopenurl.html

Adding Meta data to the NSUserActivity

NSUserActivity gives specific mentioning to the below properties 

1. eligibleForPublicIndexing 
2. expirationDate 
3. webPageURL 

Activities are private by default. When we set the eligibleForPublicIndexing, and we use the web markup to make the related website content searchable, user engagement with the item can help improve the ranking of website. 

If we don’t use the expiration date property, system will choose an expiration date.
activities are private by default. when we set an items eligibleForPublicIndexing property and we use web markup to make our related website content searchable, user engagement with the item can help ranking of our websites content. 

the webPAgeURL property is useful when the app content is also available on the website and use both NSUserActivity API in the app and the web markup for the website. In particular, we can use the webURL property to avoid duplicate indexing of the same content/ When we use the webURL property, we also require to set the requiredUserInfo property, using the keys of the userInfo dictionary that must be stored. If we don’t set the requiredUserInfoKeys property, the userInfo dictionary will be empty when the activity is restored. 

When the user performs an activity or enters the app state associated with NSUserActivity object we created, app should call becomeCurrent method to mark the activity as current. A current activity that is eligible for search is automatically added to the privat on-device index (that is CSearchableIndex). Additionally we can enable user actions within a search result such as calling a number or getting directions to a location.
If we want the activity to be eligile for search but not for handoff between devices, set eligibleForSearch property to true and eligileForHandoff property to false. 

references:


Minimal code to play Youtube Video - Android

Below given is the simple code snippet to play a video. 

public class YoutubePlayerActivity extends YouTubeBaseActivity implements YouTubePlayer.OnInitializedListener {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_youtube_player);
        playYouTubeVideo();
        
    }
    
    private void playYouTubeVideo()
    {
        YouTubePlayerView youTubeView = (YouTubePlayerView) findViewById(R.id.youtube_view);
        youTubeView.initialize("DummyKeyIzaSyBgURIAyTk3EklVgbtbiqN2Qw", this);
    }
    
    public void onInitializationFailure(YouTubePlayer.Provider provider,
                                        YouTubeInitializationResult errorReason) {
        AppUtils.errorLog("Player initialization failure!");
    }
    
    @Override
    public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player,
                                        boolean wasRestored) {
        if (!wasRestored) {
            player.cueVideo("wKJ9KzGQq0w");
            player.play();
        }
    }
}


The player.play sometimes does not play it automatically. In that case, just call loadVideo instead of cueVideo or playVideo. 

references:
https://developers.google.com/youtube/android/player/

Youtube Player Exception while adding YouTubePlayerView

When trying to create a YouTubeVideoPlayer within application, it gave below exception. And that is because the Activity hosting the YouTubePlayerView should be inherited from YouTubeBaseActivity not just a regular Activity or ActionBarActivity

Caused by: java.lang.IllegalStateException: A YouTubePlayerView can only be created with an Activity  which extends YouTubeBaseActivity as its context.
            at com.google.android.youtube.player.YouTubePlayerView.(Unknown Source)
            at com.google.android.youtube.player.YouTubePlayerView.(Unknown Source)

            at java.lang.r

References:
http://stackoverflow.com/questions/19664890/error-youtubeplayerview-xml

Android YouTube API

The Youtube player API allows user to load and play YouTube videos. Using the API, we can load or cue video into a player view embedded in applications UI. With this, we can also control the playback programmatically. 

The steps for including this are like below 

1. Download the Jar file 
2. Register the application 
3. setup the application 

In detail below are the overall steps. 

the jar file was named like YouTubeAndroidPlayerApi-1.2.2.zip. This zip file has docs, samples and the jar file for the API set.

Registering part included below items

1. On the Google API console, enable the Youtube Data API v3.  
2. there are two ways to use this API. Key and the OAuth 2.0. 

Adding the Key is simple. We can create this as Android, iOS Server or Client key. In this case, the Android key is what we needed.  

to run the sample, i tried to import the eclipse project given along with it to Android studio, but it complained saying that it needs platform 19. 

thats it! 

references:

YouTubeStandalonePlayer API

This is the simplest form to launch the player using the Intent. Using this, we can we can launch a play video, a playlist, or a video list 

The intents are like below 

YouTubeStandalonePlayer.createVideoIntent(this, DeveloperKey.DEVELOPER_KEY, VIDEO_ID, startTimeMillis, autoplay, lightboxMode);

To play a paylist, below can be done 
intent = YouTubeStandalonePlayer.createPlaylistIntent(this, DeveloperKey.DEVELOPER_KEY,PLAYLIST_ID, startIndex, startTimeMillis, autoplay, lightboxMode);

To play a list of videos, below can be used. 
intent = YouTubeStandalonePlayer.createVideosIntent(this, DeveloperKey.DEVELOPER_KEY,
                                                    VIDEO_IDS, startIndex, startTimeMillis, autoplay, lightboxMode);

Does this mechanism allows to programmatically dismiss the video player intent and come back to the original application? 

Does this mechanism allows to programmatically pause, stop, seek the item being played? 


References:
https://developers.google.com/youtube/android/player/

iOS 3D Touch

This feature is available on iPhone 6s and iPhone 6s Plus 

There are two ways to do this, 

1. Statically : This is done by defining static quick actions in the info.plist file. This is done by doing UIApplicationShortcutItems array. 
2. Dynamically 

Statically adding is pretty simple. Below is the code to do this 

UIApplicationShortcutItems<!/key>
UIApplicationShortcutItemIconFile<!/key>
icon-manage.png<!/string>
UIApplicationShortcutItemTitle<!/key>
View Nearby hotspots <!/string>
UIApplicationShortcutItemType<!/key>
com.timewarnercable.wifi-finder.viewnearby<!/string>
UIApplicationShortcutItemUserInfo<!/key>
key2<!/key>
value2<!/string>
<!/dict>
<!/dict>
UIApplicationShortcutItemIconType<!/key>
UIApplicationShortcutIconTypeCompose<!/string>
UIApplicationShortcutItemTitle<!/key>
View Usage <!/string>
UIApplicationShortcutItemType<!/key>
com.mycompany.myapp.newmessage<!/string>
UIApplicationShortcutItemUserInfo<!/key>
key2<!/key>
value2<!/string>
<!/dict>
<!/dict>
UIApplicationShortcutItemIconType<!/key>
UIApplicationShortcutIconTypeCompose<!/string>
UIApplicationShortcutItemTitle<!/key>
Manage Devices<!/string>
UIApplicationShortcutItemType<!/key>
com.mycompany.myapp.newmessage<!/string>
UIApplicationShortcutItemUserInfo<!/key>
key2<!/key>
value2<!/string>
<!/dict>
<!/dict>
UIApplicationShortcutItemIconFile<!/key>
open-favorites<!/string>
UIApplicationShortcutItemTitle<!/key>
Request Hotspot<!/string>
UIApplicationShortcutItemType<!/key>
com.mycompany.myapp.openfavorites<!/string>
UIApplicationShortcutItemUserInfo<!/key>
key1<!/key>
value1<!/string>
<!/dict>
<!/dict>

References:

PushKit Framework iOS

Instead of app keeping the persistent connections, apps can utilize the push kit framework. When push is received, the app is called to action. The action it can take could be display a notification to the user in the Notification center informing there is a call so that user can accept the call. The whole purpose of this framework is to avoid having the apps to maintain persistent socket connection with the backend servers. 

We tried to push this concept to TWC but received an almost NO response or it is moving very slow. The TWC ACME backend / SBC does not have the capability for it. The main problem from backend perspective is that, considering A call B (iOS App), A’s request needs to be queued at server, Server need send push to B, user acts on B’s popup and finally B reaches to the server to grab the pending call. But today what happens is that, when server receives call from A, it checks if B is actively having a socket and if it does not find, immediately sends back a 403 User not registered response to A. Servers needs to have a change for this to be fully utilized. If the server is willing to change, it will be a very good advantage to the user, the battery life will be more!. 

Overall, Below are advantages of PushKit 

1. The device is woken up only when VoIP push occur. saving energy. Apps no need to maintain persistent connection with server. 
2. Unlike normal push messages, the VoIP push directly goes into the app first. This means that app can do some background task such as if user has set Busy, then it won’t ring, instead send a busy signal back to the server. 
3. VoIP pushes are considered high priority ones and delivered without delay. 
4. VoIP push can contain more data than normal push messages.  
5. App is automatically launched when VoIP push is received. 
6. App is given runtime to process push even if app is running in background. 

This is supported in iOS 8.0 and later. 

Below are the process involved in this

1. Declare Background mode as VoIP => Like conventional VoIP applications, prior to PushKit, app should declare background mode as VoIP so that application can run in background. 
2. Create VoIP certificate for the app. Each app which wish to use PushKit, needs to have separate VoIP services certificate. This certificate allows an App’s backend Notification service to reach to Apple’s VoIP service.


REferences:

How does the Speed test app work - Legacy HTTP

There are mainly three tests to be performed 

1. Latency 
2. Download Test
3. Upload Test 

Latency Test is performed by measuring the time it takes to get a response for a HTTP request sent to a web server. This test is repeated multiple times with the lowest value determining the final result. 

Download Test is performed by downloading small binary files to estimate the connection speed. Based on this result, one of several file sizes is selected to use the real download test. This test is performed with cache prevention via random string appended to each download. Throughput samples are received at upto 30 times per second. These samples are then aggregated to 20 slices (each being 5% of the samples). The remaining slices are averaged together to get the final result. 

Upload test is performed by sending small amount of random data generated in the client and sent to the web server to estimate the connection speed. Based on the result, an appropriately sized chunk of randomly generated data is selected for upload. The upload test is then performed in chunks of uniform size, pushed to the server side script via POST. normally it creates 4 HTTPS threads as well to saturate the connection. Chunks are sorted by speed and the fastest half is averaged to eliminate anomalies and determine the result. 

Deciding the number of threads 

Typically, for e.g. Speedtest app uses unto 4 HTTP threads. However, it will use only more than 2 threads only if it is required to measure the speed accurately. This is done to minimize the HTTP overhead in lowest connection speeds. After the pre-test, if the connection is at least 4Mbps, then it will use 4 threads. However, there is a catch. On old browsers, only two connections per domain might be supported, in this case, the sub domain might be required for the 3rd and 4th connection. 

References

FAQs on Speed test

What is Ping, download speed and upload speed? 
The ping is reaction time of the connection how fast we get response after one has sent out the request. A fast ping means more responsive connection. Ping is measured in milliseconds

The download speed is how fast one can pull the data from server to you. Most connections are designed to be faster in download than upload. Download speed is measured in Mbps. 

The upload speed is how fast the data is sent from device to others. Upload speed is measured in Mbps again. 

Some of the common network speed requirement for apps are like below 

Skype  voice call : 0.1 Mbps upload, 0.1 Mbps download 
Video call : 0.5Mbps upload , 0.5 Mbps download 
HD video call : 1.5 Mbps upload , 1.5 Mbps download 

What could be reasons of having difference speed between computers and devices? Could be the ones below 

1. Differences in available bandwidth : Needs to ensure the tests on both these are not done together 
2. Differences in connection : Need to ensure both tests are performed in same connection 
3. Differences in hardware : Typically, phone and tablets are having less sophisticated WiFi antenna than larger devices like laptops. This differnce could negatively impact wifi speed especially in areas of high interference on the 2.4GHz frequency. 

References:

Speed test TCP test components

Latency/Jitter : This test is performed by measuring the time it takes for the server to reply to a request from the user’s client. The client sends message to the server, upon receiving that message, the server sends reply back. The round trip time is measured in ms. 

Download: 
1. Client establishes multiple connections to the server over port 8080. The client requests the server to send an initial chunk of data
2. The client calculates the real time speed of transfers, then adjusts the chunk size and buffer size based on this calculation to maximize the usage of network connection
3. As the chunks are received by the client, the client will request more chunks throughout the duration of the test. 
4. During the first half of the test, the client will establish extra connections to the server if it determines extra threads are required to more accurately measure the download speed. 
5. The test ends once the configured amount of time has been reached. 

Upload: 
1. The client establishes multiple connections with the server over port ands sends initial data 
2. the client calculates the real time speed of the transfers and adjusts the chunk size and buffer size based on it to maximize the network connection usage. 
3. as the chunks are received by the server, client will send more chunks throughout the duration of the test 
4. During the first half of the test, the client will establish extra connections to the server if it determines additional threads are required to more accurately measure the upload speed. 
5. The test ends once configured amount of time has reached  

references:

iOS Search Using NSUserActivity

In addition to support handoff, using NSUserActivity will allow in iOS 9.0 and later below items 

1. Index activities as users perform them in the app. Activities could be creating or viewing content, viewing a set of items (such as result list) or visiting navigation point within the app 
2. Mark specific items available for public searching 
3. provide indexable meta data about an item which gives user rich information in search results 

To provide best search results, one should avoid creating multiple NSUserActvities objects at one time. Also, NSUSerActivity is not intended for App specific arbitrary data. For indexing App content, need to use the core spot light framework. Also can use the relatedUniqueIdentifier to link the items together 

Using NSUSerActivity also lets one to take advantage of Siri suggestions and smart reminders. Siri suggestions are displayed in the core spotlight search screen and can incldue searchable activities. Users can use smart reminders to be reminded about specific content related to the app. When users receive a smart reminder, the activity they specified is displayed in the reminder. 

As the user uses the app, we can create activity objects associated with various navigation points and app states. Each item is added to the on-device index by default. In iOS 9.0 Making a public item as eligible for public indexing also adds it to on-device index and confers to additional advantage: When we use web markup to make the related content searchable, user engagement with publicly eligible search results from the app can help improve the ranking of website content 

to make an activity or navigation point searchable, create an NSUserActivity object to represent it, Use NSUserActivity to represent it. it is like below 

var activity: NSUserActivity = NSUserActivity(activityType:”com.mycompany.myContentType”);
activity.title = “My Activity Title”
activity.userInfo = [“id”,”http://www.google.com”]
activity.eligibleForSearch = true;


References:

Wednesday, January 13, 2016

Android - Keeping the screen on

Multiple approaches were discussed  in the forum thread. Below were tried and few results on that. 

PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "no sleep");
wakeLock.acquire();

Below permission had to be requested in the Manifest file.

"android.permission.WAKE_LOCK" />

In the service on Destroy, below code needs to be added as well. 

wakeLock.release();

However, this actually did not work, screen was locked even though this was specified. Reading more on the API Documentation, apart from the PARTIAL_WAKE_LOCK, it also had FULL_WAKE_LOCK or DIM but these are now deprecated

The API documentation suggests something like below 

getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
The above cannot be called from Service, instead needs to be called from Activity or Fragment. 

By calling the above from an activity, below was my experience on Android lollipop device. 

1. With the activity that called the API on the screen, the screen never locked up 
2. With the activity that called the API pushed to background, but with an overlay window on the screen, the screen gets locked up
3. With the app killed, definitely the screen gets locked up

References: