Streaming Measurement in iOS
This chapter describes the basic use of the sensor for the measurement of streaming content.
Properties of the Library
Property | Default | Description |
---|---|---|
tracking | true | If this property is set to |
offlineMode | false | If this property is set to |
debug | false | If the value is set to true , the debug messages are issued by the library |
timeout | 10 | Timeout Setting for the HTTP-Request |
...
Lifecycle of the Measurement
...
When you start the app the sensor must be instantiated once. It is not possible to change the site name or the application name after this call.
Code Block | ||||
---|---|---|---|---|
| ||||
KMA_SpringStreams *spring = [KMA_SpringStreams getInstance:@"sitename" a:@"TestApplication"]; |
...
Note |
---|
The site name and application name is specified by the operator of the measurement system. |
From this point on, the method getInstance
must be used .
Code Block | ||||
---|---|---|---|---|
| ||||
KMA_SpringStreams *spring = [KMA_SpringStreams getInstance]; |
Implementation of the Adapter
...
Code Block | ||||
---|---|---|---|---|
| ||||
@protocol@interface KMA_Player_Meta <NSObject>: @required -(NSString*) getPlayerName; -(NSString*) getPlayerVersion; -(int) getScreenWidth; -(int) getScreenHeight; @end @interface StreamAdapter : NSObject { } - (id) init:(NSObject *)stream; -(NSObject<Meta>NSObject<NSCoding, NSCopying> { } @property (retain,readwrite) NSString *playername; @property (retain,readwrite) NSString *playerversion; @property (assign,readwrite) int screenwidth; @property (assign,readwrite) int screenheight; @end @protocol KMA_StreamAdapter @required -(KMA_Player_Meta*) getMeta; -(int) getPosition; -(int) getDuration; -(int) getWidth; -(int) getHeight; @end |
...
|
Beginning of the Measurement
This chapter explains step by step how a streaming content is transferred to the library for the measurement.
Info |
---|
In the library an adapter for class MPMoviePlayerController AVPlayerViewController from the MediaPlayer.framework AVKit ramework is settled. The source code for this implementation can be found in Appendix Anhang A and in the library. |
The following code block shows an example for the use of the library.
Code Block | ||||
---|---|---|---|---|
| ||||
... MPMoviePlayerController @property (strong,nonatomic) AVPlayerViewController *player = [[[MPMoviePlayerController alloc] initWithContentURL: theURL] autorelease]; ... adapterplayer = [[MediaPlayerAdapterAVPlayerViewController alloc] adapter:playerinit]; player.player NSMutableDictionary= * atts = [[NSMutableDictionary alloc] init]; [atts setObject:@"iOS/teststream" forKey:@"stream"]; // mandatory // [atts setObject:@"4711" forKey:@"cq"]; //optional see implementation guideline // [atts setObject:@"mobile[AVPlayer playerWithURL:url]; self.player.view.frame = self.videoPlaceholder.frame; [self.view addSubview:self.player.view]; KMA_MediaPlayerAdapter *adapter = [[KMA_MediaPlayerAdapter alloc] adapter:self.player]; //Call track to track the video player NSMutableDictionary * atts = [[NSMutableDictionary alloc] init]; [atts setObject:@"live/iOS/teststream" forKey:@"ctstream"]; //optional see implementation guideline Stream *stream = [spring track:adapter atts:atts]; [atts release]; ... |
...
mandatory
// [atts setObject:@"test" forKey:@"cq"]; //optional see implementation guideline
// [atts setObject:@"1369" forKey:@"vt"]; //optional see implementation guideline
// [atts setObject:@"testSiteName" forKey:@"sitename="]; //optional see implementation guideline
Stream *stream = [self.spring track:adapter atts:atts];
[atts release];
... |
First, the player and the object needs to be instantiated, that is able to deliver the current position on a stream in seconds. In the second step the adapters must be produced, which implements this requirement accurately.
Then an NSDictionary is generated in order to formulate more detailed information about the stream. Therefore the attribute stream must always be specified
Info |
---|
The attribute |
...
Info |
---|
A stream is measured as long as the application is in the foreground. When the application goes into the background, the current status is transmitted to the measurement system and the measurement stops. If the stream should be measured again, when the application will come back to the foreground, the method |
...
End of the Measurement
After the measurement of a stream has been started, this stream is measured by the sensor. The measurement can be stopped by calling the method stop
on the stream object. All measurements will be automatically stopped by the library, when the application goes into the background.
...
Info |
---|
If the stream should be measured again, when the application comes to the foreground or after the method |
...
Foreground- and Background Actions
Info |
---|
Once the application is in the background all measurements in the library are stopped, i.e. when the application goes to the foreground, the measurement on a stream must be restarted. |
Ending the application
Appendix A
...
In the following example, the adapter has been implemented for the media player
from the standard API.
...
If the application is closed, the method unload
can be called. This call sends the current state of the measurements to the measuring system and then terminates all measurements. This method is automatically called by the library, when the application goes into the background.
...
...
[[SpringStreams getInstance] unload];
application goes into the background.
Code Block | ||||
---|---|---|---|---|
| ||||
...
[[KMA_SpringStreams getInstance] unload]; |
Appendix A
Anchor | ||||
---|---|---|---|---|
|
In the following example, the adapter has been implemented for the media player
from the standard API.
Code Block |
---|
// // KMA_MediaPlayerAdapter.m // KMA_SpringStreams // // Created by Frank Kammann on 26.08.11. // Copyright 2011 spring GmbH & Co. KG. All rights reserved. // #import "KMA_SpringStreams.h" /** * Implementation of a KMA_StreamAdapter. * * @see KMA_StreamAdapter */ @implementation KMA_MediaPlayerAdapter AVPlayerViewController *controller; KMA_Player_Meta *meta; /** * Initialize the adapter with the MPMoviePlayerController * * @see http://developer.apple.com/library/ios/#documentation/mediaplayer/reference/MPMoviePlayerController_Class/Reference/Reference.html * */ - (KMA_MediaPlayerAdapter*)adapter:(AVPlayerViewController *)player { //if (self) { meta = [[KMA_Player_Meta alloc] init]; meta.playername = @"AVPlayerViewController"; controller = player; //} return [super init]; } /** * Returns the meta object. * * @see MediaPlayerMeta */ - (KMA_Player_Meta*) getMeta { return meta; } /** * Returns the current position on the KMA_Stream in seconds by calling * the method MPMediaPlayback.currentPlaybackTime * * @see http://developer.apple.com/library/ios/#documentation/mediaplayer/reference/MPMediaPlayback_protocol/Reference/Reference.html#//apple_ref/occ/intf/MPMediaPlayback# */ - (int) getPosition { int position = CMTimeGetSeconds(controller.player.currentItem.currentTime); // in initialize phase in controller this value is set to -2^31 if(position < 0) position = 0; return position; } /** * Returns the duration of the KMA_Stream in seconds by calling * the method MPMediaPlayback.duration. * */ - (int) getDuration { return CMTimeGetSeconds(controller.player.currentItem.duration); } /** * Returns the width by the controller view. * * @return contoller.view.bound.size.width */ - (int) getWidth { return controller.view.bounds.size.width; } /** * Returns the height by the controller view. * * @return contoller.view.bound.size.height */ - (int) getHeight { return controller.view.bounds.size.height; } @end @implementation KMA_Player_Meta /** * Returns the player name * * @return the string "MediaPlayer" */ @synthesize playername; /** * Returns the player version. * The itselfs has no version so the system version is delivered. * * @see http://developer.apple.com/library/ios/#documentation/uikit/reference/UIDevice_Class/Reference/UIDevice.html * * @return The version my calling [UIDevice currentDevice].systemVersion */ @synthesize playerversion; /** * Returns the screen width my calling the method * [[UIScreen mainScreen] bounds].screenRect.size.width * * @see http://developer.apple.com/library/ios/#documentation/uikit/reference/UIScreen_Class/Reference/UIScreen.html * * @return the width */ @synthesize screenwidth; /** * Returns the screen width my calling the method * [[UIScreen mainScreen] bounds].screenRect.size.height * * @see http://developer.apple.com/library/ios/#documentation/uikit/reference/UIScreen_Class/Reference/UIScreen.html * * @return the height */ @synthesize screenheight; - (id) init { self = [super init]; if (self) { self.playername = @"iOS Player"; self.playerversion = [UIDevice currentDevice].systemVersion; CGRect screenRect = [[UIScreen mainScreen] bounds]; self.screenwidth = screenRect.size.width; self.screenheight = screenRect.size.height; } return self; } - (id) copyWithZone:(NSZone *)zone { id copy = [[[self class] alloc] init]; if (self) {copy) { // Copy NSObject subclasses [copy setPlayername:[self.playername if(player == nil)copyWithZone:zone]]; [copy setPlayerversion:[self.playerversion copyWithZone:zone]]; @throw [NSException exceptionWithName:@"IllegalArgumentException" // Set primitives [copy setScreenwidth:self.screenwidth]; [copy setScreenheight:self.screenheight]; } return copy; } reason:@"player may- not be null"(NSString *)description { return [NSString stringWithFormat:@"Meta pl=%@ plv=%@ sx=%ld sy=%ld", self.playername, self.playerversion, userInfo:nil]; controller = player;(long)self.screenwidth, } return (long)self.screenheight]; } - (NSString*) getPlayerName {(void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:self.playername forKey:@"playername"]; return [encoder encodeObject:self.playerversion forKey:@"MediaPlayerplayerversion"]; } - (NSString*) getPlayerVersion { [encoder encodeInt:self.screenwidth forKey:@"screenwidth"]; return [UIDevice currentDevice].systemVersion[encoder encodeInt:self.screenheight forKey:@"screenheight"]; } - (intid) getScreenWidthinitWithCoder:(NSCoder *)decoder { CGRectself.playername screenRect = [[UIScreen mainScreen] bounds];decoder decodeObjectForKey:@"playername"]; self.playerversion = return screenRect.size.width; } - (int) getScreenHeight { [decoder decodeObjectForKey:@"playerversion"]; self.screenwidth = [decoder decodeIntForKey:@"screenwidth"]; CGRect screenRectself.screenheight = [[UIScreen mainScreen] boundsdecoder decodeIntForKey:@"screenheight"]; return screenRect.size.heightself; } @end |
Implementation of the URL Scheme in iOS
...
you can edit it in any editor, if you do so, please insert the following code:
Code Block <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLName</key> <string>***</string> //please change *** to your URL name, not so important <key>CFBundleURLSchemes</key> <array> <string>***</string> //very important, please replace </array> </dict> </array>
Or you can edit this in xcode, add an item into
Info.plist
, named "URL types", expand "Item 0" under "URL types", and add two items: "URL identifier", "URL Schemes".For "URL identifier", assign your identifier, and for "URL Schemes", add a new item within it named "Item0", REGISTER A UNIQUE URL SCHEME FOR YOUR APP, VERY IMPORTANT!
It should be like the following:
How to use the different Files in the Library Package
File | Description |
---|---|
spring-appsensor-device.a | This is the version that has been compiled with ARM support and which is intended for execution on iOS devices |
spring-appsensor-simulator.a | This is the version that has been compiled with x86 support and which is intended for execution on iOS simulator |
spring-appsensor-fat.a | This is a combined version of the two libraries above, which can be executed on both, iOS devices and iOS simulator because it contains code for ARM and x86 execution. This file is called "fat" as it is roughly double the size (because it combines both versions). |
Note |
---|
If size does not matter for the app, the "fat" version is the carefree option to be used for execution on simulator and real devices. |
Include Page Tutorial on how to import KMA measurement Objective-C library into Swift project Tutorial on how to import KMA measurement Objective-C library into Swift project