IntegrationExamples

IOS

IntegrationExamples.IOS History

Hide minor edits - Show changes to output

February 20, 2014, at 06:49 AM by 184.66.20.248 -
Changed lines 340-341 from:
[@ Sample coming soon@]
to:
[@// Is this a Quest?
        if (self.aiWizard) {
           
            // Begin Combat (Event #21)
            // For the purpose of this demo, it is considered a Begin Combat Event when a the MatchStatus changes to Playing during a Quest.
            User *user = [UserService.shared currentUser];
            [AnalyticsService.shared.kApi combatStart:[NSDate date] theAccountId:user.userId theCharacterId:user.name theShardId:0 theNpcId:self.aiWizard.npcId theAreaId:0 theX:0 theY:0 theZ:0 theBeginAreaName:@""];
@]
Changed lines 361-362 from:
[@ Sample coming soon@]
to:
[@// End Combat (Event #22)
        // For the purpose of this demo, we consider the end of a quest an End Combat event.
        [AnalyticsService.shared.kApi combatEnd:[NSDate date] theAccountId:currentUser.userId theCharacterId:currentUser.name theShardId:0 theNpcId:npcId theAreaId:0 theX:0 theY:0 theZ:0 theEndAreaName:@""];
@]
Changed lines 379-380 from:
[@ Sample coming soon@]
to:
[@ } else if (wizard == self.aiWizard) {
                   
                    // Kill NPC (Event #23)
                    // For the purpose of this demo, we consider it a Kill NPC event when the player kills the AI Wizard.
                    [AnalyticsService.shared.kApi logKillNpc:[NSDate date] theAccountId:user.userId theCharacterId:user.name theShardId:0 theCharacterLvl:user.wizardLevel theNpcId:self.aiWizard.npcId];
@]
Changed lines 398-399 from:
[@ Sample coming soon@]
to:
[@if (self.challenge) {
        // PVP Duel (Event #25)
        // For the purpose of this demo, we consider the end of a challenge a PVP Duel event.
        [AnalyticsService.shared.kApi logPvpDuel:[NSDate date] theAccountId:currentUser.userId theCharacterId:currentUser.name theShardId:0 isWinner:didWin];
    }
@]
Changed lines 418-419 from:
[@ Sample coming soon@]
to:
[@// Was the player or AI Wizard killed?
                if (wizard == self.currentWizard) {
                   
                    // Player Death (Event #26)
                    // For the purpose of this demo, we consider it a Player Death event when the AI Wizard kills the player's Wizard.
                    [AnalyticsService.shared.kApi logPlayerDeath:[NSDate date] theAccountId:user.userId theCharacterId:user.name theShardId:0 theKillerNpcId:self.aiWizard.npcId theDeathType:@"NA" theAreaId:0 theX:0 theY:0 theZ:0 theAreaName:@""];
@]
Changed lines 439-455 from:
From MatchViewController.m Line 206, 345, 351: \\
[@ Sample coming soon@]

%right%[[#top|Back to Top]]
----

!!!!'''Reward (Event ID #49)'''
It will be considered a Reward event when the player's wizard level is increased as a result of completing a quest, casting spells, or winning a duel against another player who has a greater wizard level than their own
.

'+'''Parameters'''+'
|| border=1 rules=rows frame
=hsides
||! Parameter ||! Value ||! Note ||
|| REWARD TYPE || 0 || Zero since only recording one type of Reward||
|| REWARD ID ||
"Wizard Level" || Since the only recorded Reward is gaining a Wizard level||
|| ITEM TYPE || 0 || Zero since no item is being rewarded||
|| REWARD COUNT || || The player's new Wizard level||

to:
From MatchViewController.m Line 206: \\
[@- (void)createMatchWithWizard:(Wizard *)wizard withLevel:(QuestLevel *)level {
    self.questLevel = level;
    [AnalyticsService event:@"match"];
    [AnalyticsService event:@"match-quest"];   
   
    // Challenge (Event #32)
    // For the purpose of this demo, we consider accepting a quest a Challenge event
.
    User *user = [UserService.shared currentUser];
 
   [AnalyticsService.shared.kApi logChallenge:[NSDate date] theAccountId:user.userId theCharacterId:user.name theShardId:0 challengeId:level.name challengeType:@"Kill An NPC or Multiple NPCs" challengeStatus:@"Accepted"];@]
Changed lines 451-459 from:
From QuestService.m Line 80: \\
[@ Sample coming soon@]

From SpellbookService.m Line 111: \\
[@ Sample coming soon@]

From UserFriendService.m Line 100: \\
[@ Sample coming soon@
]
to:
From MatchViewController.m Line 345, 351: \\
[@if (didFinish) {
   
      
           // Challenge (Event #32)
            // For the purpose of this demo, we consider completing a quest a Challenge event.
            [AnalyticsService.shared.kApi logChallenge:[NSDate date] theAccountId:currentUser.userId theCharacterId:currentUser.name theShardId:0 challengeId:self.questLevel.name challengeType:@"Kill An NPC or Multiple NPCs" challengeStatus:@"Completed"];
           
        } else {
           
            // Challenge (Event #32)
            // For the purpose of this demo, we consider leaving a quest a Challenge event.
            [AnalyticsService.shared.kApi logChallenge:[NSDate date] theAccountId:currentUser.userId theCharacterId:currentUser.name theShardId:0 challengeId:self.questLevel.name challengeType:@"Kill An NPC or Multiple NPCs" challengeStatus:@"Abandoned"];
        }
@]
Changed lines 468-470 from:
!!!!'''Off-Game-Interaction Sender (Event ID #7)'''
The game allows a player to send a download link to others for the game via Facebook by posting on their Facebook friends' walls.  It will be considered an OGI Sender event when the player sends a message about the game to one of their Facebook friends.
to:
!!!!'''Reward (Event ID #49)'''
It will be considered a Reward event when the player's wizard level is increased as a result of completing a quest, casting spells, or winning a duel against another player who has a greater wizard level than their own.
Changed lines 474-480 from:
|| SENDER ACCOUNT ID || || The player's user id who shared to Facebook||
|| SENDER ACCOUNT NAME || || The player's wizard name who shared to Facebook||
|| RECEIVER ACCOUNT ID
|| || The Facebook id of the receiving friend||
|| RECEIVER ACCOUNT NAME ||
|| The Facebook id of the receiving friend||
|| OGI LOCATION || "Facebook" || ||
|| OGI CATEGORY || "Posts on Social Media" ||
||
to:
|| REWARD TYPE || 0 || Zero since only recording one type of Reward||
|| REWARD ID || "Wizard Level" || Since the only recorded Reward is gaining a Wizard level||
|| ITEM TYPE || 0 || Zero since no item is being rewarded||
|| REWARD COUNT ||
|| The player's new Wizard level||
Changed lines 480-482 from:
From MatchmakingViewController.m Line 863: \\
[@ Sample coming soon@]

to:
From QuestService.m Line 80: \\
[@if (questLevel.wizardLevel > currentUser.wizardLevel) {
            currentUser.wizardLevel += 1;
            [achievements addObject:[Achievement wizardLevel:currentUser]];
           
            // Reward (Event #49)
            // For the purpose of the demo, we consider a Reward event when the user gains a Wizard level.
            [AnalyticsService.shared.kApi logReward:[NSDate date] theAccountId:currentUser.userId theCharacterId:currentUser.name theShardId:0 theRewardType:0 theRewardId:@"Wizard Level" theItemType:0 theRewardCount:currentUser.wizardLevel];@]

From SpellbookService.m Line 111: \\
[@if (record.level > beforeLevel) {
            [achievements addObject:[Achievement spellLevel:record]];
            [AnalyticsService event:[NSString stringWithFormat:@"spell-unlock-%@-%i", type, record.level]];
            if (record.level > SpellbookLevelNovice) {
                currentUser.wizardLevel += 1;
                [achievements addObject:[Achievement wizardLevel:currentUser]];
               
                // Reward (Event #49)
                // For the purpose of the demo, we consider a Reward event when the user gains a Wizard level.
                [AnalyticsService.shared.kApi logReward:[NSDate date] theAccountId:currentUser.userId theCharacterId:currentUser.name theShardId:0 theRewardType:0 theRewardId:@"Wizard Level" theItemType:0 theRewardCount:currentUser.wizardLevel];
            }@]

From UserFriendService.m Line 100: \\
[@if (friend.wizardLevel > user.wizardLevel) {
            user.wizardLevel += 1;
            [achievements addObject:[Achievement wizardLevel:user]];
           
            // Reward (Event #49)
            // For the purpose of the demo, we consider a Reward event when the user gains a Wizard level.
            [AnalyticsService.shared.kApi logReward:[NSDate date] theAccountId:user.userId theCharacterId:user.name theShardId:0 theRewardType:0 theRewardId:@"Wizard Level" theItemType:0 theRewardCount:user.wizardLevel];@]

Changed lines 514-516 from:
!!!!'''Friend Addition (Event ID #43)'''
When the first duel between two players ends, they are now considered "Frenemies" and will always appear in their Lobby, even if they are logged out.  It will be considered a Friend Addition Event when the first duel ends between two players and they become "Frenemies".
to:
!!!!'''Off-Game-Interaction Sender (Event ID #7)'''
The game allows a player to send a download link to others for the game via Facebook by posting on their Facebook friends' walls.  It will be considered an OGI Sender event when the player sends a message about the game to one of their Facebook friends.
Changed lines 520-524 from:
|| SENDER ACCOUNT ID ||  || The player's user id who initiated the duel||
|| SENDER ACCOUNT NAME || || The player's wizard name who initiated the duel||
|| RECEIVER ACCOUNT ID ||  || The player's user id who was challenged to the duel||
|| RECEIVER ACCOUNT NAME || || The player's wizard name who was challenged to the duel||
to:
|| SENDER ACCOUNT ID || || The player's user id who shared to Facebook||
|| SENDER ACCOUNT NAME || || The player's wizard name who shared to Facebook||
|| RECEIVER ACCOUNT ID || || The Facebook id of the receiving friend||
|| RECEIVER ACCOUNT NAME || || The Facebook id of the receiving friend||
|| OGI LOCATION || "Facebook" || ||
|| OGI CATEGORY || "Posts on Social Media" ||
||
Changed lines 528-530 from:
From UserFriendService.m Line 84: \\
[@ Sample coming soon@]
to:
From MatchmakingViewController.m Line 863: \\
[@[UserFriendService.shared openFeedDialogTo:friendIds complete:^{
        [AnalyticsService event:@"invite-facebook-friend-complete"];
       
        // OGI Sender (Event #7)
        // For the purpose of the demo, we consider when the user posts on a friends Facebook an OGI Sender event
        User *user = [UserService.shared currentUser];
        [AnalyticsService.shared.kApi logOgiSend:[NSDate date] sendAccId:user.userId sendCharId:user.name recvAccId:[friendIds lastObject] recvCharId:[friendIds lastObject]  theShardId:0 theOgiLocation:@"Facebook" theOgiCategory:@"Posts on Social Media"];
@]
Changed lines 540-542 from:
!!!!'''Friend Deletion (Event ID #44)'''
After a player becomes the user's "Frenemy", the user can remove them as a "Frenemy" by swiping their entry on the Lobby list and pressing the "Defrenemy" button.  It will be considered a Friend Deletion event when a user removes another player as a "Frenemy".
to:
!!!!'''Friend Addition (Event ID #43)'''
When the first duel between two players ends, they are now considered "Frenemies" and will always appear in their Lobby, even if they are logged out.  It will be considered a Friend Addition Event when the first duel ends between two players and they become "Frenemies".
Changed lines 546-550 from:
|| SENDER ACCOUNT ID ||  || The player's user id who removed the "Frenemy"||
|| SENDER ACCOUNT NAME || || The player's wizard name who removed the "Frenemy"||
|| RECEIVER ACCOUNT ID || || The player's user id who was removed as a "Frenemy"||
|| RECEIVER ACCOUNT NAME || || The player's wizard name who was removed as a "Frenemy"||
to:
|| SENDER ACCOUNT ID ||  || The player's user id who initiated the duel||
|| SENDER ACCOUNT NAME || || The player's wizard name who initiated the duel||
|| RECEIVER ACCOUNT ID ||  || The player's user id who was challenged to the duel||
|| RECEIVER ACCOUNT NAME || || The player's wizard name who was challenged to the duel||
Changed lines 552-554 from:
From MatchmakingViewController.m Line 465: \\
[@ Sample coming soon@]
to:
From UserFriendService.m Line 84: \\
[@// Was this the first challenge with this friend?
    if (friend.gamesTotal == 0) {
       
        // Friend Additon (Event #43)
        // For the purpose of this demo, we consider the end of the first game against a new player a Friend Addition event
        [AnalyticsService.shared.kApi logFriendAdd:[NSDate date] sendAccId:user.userId sendCharId:user.name recvAccId:friend.userId recvCharId:friend.name];
@]
Changed lines 563-565 from:
!!!!'''Custom Slot (Event ID #54)'''
The Katana API has an empty slot to allow for a Custom event to be recorded that is unique to the particular application.  The custom event recorded here is a "Block".  During a duel a player can cast a spell that prevents them from being hit by a spell cast by an opposing player or NPC.
to:
!!!!'''Friend Deletion (Event ID #44)'''
After a player becomes the user's "Frenemy", the user can remove them as a "Frenemy" by swiping their entry on the Lobby list and pressing the "Defrenemy" button.  It will be considered a Friend Deletion event when a user removes another player as a "Frenemy".
Changed lines 569-572 from:
|| CUSTOM ACTION ||  "Block" || || 
|| CUSTOM ACTION TYPE || 
"Spell Interaction" || ||
|| CUSTOM ACTION VALUE
|| 0 || Zero since there is only one state for a Block ||
to:
|| SENDER ACCOUNT ID ||  || The player's user id who removed the "Frenemy"||
|| SENDER ACCOUNT NAME || || The player's wizard name who removed the "Frenemy"||
|| RECEIVER ACCOUNT ID || || The player's user id who was removed as a "Frenemy"||
|| RECEIVER ACCOUNT NAME || || The player's wizard name who was removed as a "Frenemy"
||
Changed lines 575-577 from:
From Match.m Line 522: \\
[@ Sample coming soon@]
to:
From MatchmakingViewController.m Line 465: \\
[@[UserFriendService.shared user:self.currentUser removeFrenemy:user];
           
            // Friend Deletion (Event #44)
            // For the purpose of this demo, we consider removing a Frenemy a Friend Deletion event.
            [AnalyticsService.shared.kApi logFriendDelete:[NSDate date] sendAccId:self.currentUser.userId sendCharId:self.currentUser.name recvAccId:user.userId recvCharId:user.name];@]

%right%[[#top|Back to Top]]
----

!!!!'''Custom Slot (Event ID #54)'''
The Katana API has an empty slot to allow for a Custom event to be recorded that is unique to the particular application.  The custom event recorded here is a "Block".  During a duel a player can cast a spell that prevents them from being hit by a spell cast by an opposing player or NPC.

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| CUSTOM ACTION ||  "Block" || || 
|| CUSTOM ACTION TYPE ||  "Spell Interaction" || ||
|| CUSTOM ACTION VALUE || 0 || Zero since there is only one state for a Block ||

'+'''Sample'''+' \\

From Match.m Line 522: \\
[@ // Did the main player destory the opponents attack Spell?
        if (main.creator != self.currentWizard
            && main.status == SpellStatusDestroyed
            && main.isWall == NO) {

            // Custom Slot - Block (Event #54)
            // For the purpose of this demo, we are using the Custom Slot event when the player blocks the opponents attack Spell.
            User *user = [UserService.shared currentUser];
            [AnalyticsService.shared.kApi logCustomAction:[NSDate date] theAccountId:user.userId theCharacterId:user.name theCustomAction:@"Block" theCustomActionType:@"Spell Interaction" theCustomActionValue:0];@]
February 20, 2014, at 06:31 AM by 184.66.20.248 -
Changed lines 51-52 from:
[@ Sample coming soon@]
to:
[@self.currentUser = user;

// Login (Event #1)
// For the purpose of this demo, we consider it to be a Login event when the currentuser attribute is
then assigned.
[AnalyticsService.shared.kApi logLogin:[NSDate date] theAccountId:user.userId theCharacterId:user.name
theshardld:@ thePlatforn:@"ioS" theAreaId:@ theAreaName:@”"];
@]
Changed lines 73-74 from:
[@ Sample coming soon@]
to:
[@//Logout Event #2
//For the purpose of this demo, we consider it to be a ‘ when the app terminates.
User aruscr = [UserService.shared currentllserl;
[AnalyticsService.shared.kApi logLogout:[NSDate date] theAccountId:user.userId theCharacterId:user.name];
@]
Changed lines 95-96 from:
[@ Sample coming soon@]
to:
[@// Subscription Change (Event #3)
            // For the purpose of this demo, we consider connecting with Facebook a Subscription Change event.
            [AnalyticsService.shared.kApi putSubChange:[NSDate date] theAccountId:user.userId theSubStatus:@"Active" theSubType:@"Premium" theSubValue:0 theExpireTs:[[NSDate date] dateByAddingTimeInterval:3.15569e7]]; // Expires in 1 year
@]
Changed lines 117-118 from:
[@ Sample coming soon@]
to:
[@        if (!user) {
            user = [ObjectStore.shared insertNewObjectForEntityForName:self.entityName];
            user.userId = [self generateUserId];
            user.isMain = YES;
            user.name = [self randomWizardName]; // [NSString stringWithFormat:@"Guest%@", [IdService randomId:4]];
            user.isGuestAccount = YES;
            user.wizardLevel = 1;
//            user.questLevel = 10;
            user.color = [UIColor blackColor];
            NSLog(@"UserService.currentUser: GENERATED %@", user.userId);
           
            // Check if this is the first run.
            NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
            if (![defaults objectForKey:@"firstRun"]) {
               
                // Create Account (Event #9)
                // For the purpose of this demo, we consider it to be a Create Account event when a new user is created on the first run.
                [AnalyticsService.shared.kApi loadAccountCreate:[NSDate date] theAccountId:user.userId theAccountType:@"Free" theAccLang:@"en-US" theAccCountry:@"US" theAccGender:@"N" theAccDateOfBirth:[NSDate dateWithTimeIntervalSinceReferenceDate:0] theAccCurrencyBal:0 thePlatform:@"iOS"];
               
                // Add a key to defaults to indicate the first run.
                [defaults setObject:[NSDate date] forKey:@"firstRun"];
                [[NSUserDefaults standardUserDefaults] synchronize];
            }@]

Changed lines 157-158 from:
[@ Sample coming soon@]
to:
[@if (spellToCast) {
        self.castSpell = spellToCast;
        self.lastSuccessfulSpell = self.castSpell;
       
        //User *user = [UserService.shared currentUser];
       
        // Initialize Item (Event #15)
        // For the purpose of the demo, we consider the creation of a valid spell an Initialize Item event.
        [AnalyticsService.shared.kApi loadItem:[NSDate date] theItemId: spellToCast.itemId theItemName:spellToCast.name theItemType:@"Weapons" theItemSegment:@"INGAME" createAccountId:@"" createCharacterId:@""];
@]
Changed lines 183-184 from:
[@ Sample coming soon@]
to:
[@-(BOOL)castSpell:(Spell *)spell {
    [self.ai opponent:self.currentWizard didCastSpell:spell atTick:self.timer.nextTick];
    BOOL success = [self player:self.currentWizard castSpell:spell currentTick:self.timer.nextTick];
   
    if (success) {
        [self.mainPlayerSpellHistory addObject:spell.type];
       
        // Item Used (Event #16)
        // For the purpose of the demo, we consider casting a spell an Item Used event.
        User *user = [UserService.shared currentUser];
        [AnalyticsService.shared.kApi logItem:[NSDate date] theAccountId:user.userId theCharacterId:user.name theCharacterLvl:user.wizardLevel theShardId:0 theItemId:spell.itemId theItemName:spell.name theItemCount:0 theAreaId:0 theAreaName:@"" theX:0 theY:0 theZ:0];
@]
Changed lines 209-210 from:
[@ Sample coming soon@]
to:
[@// Match starts.... NOW
    [self.match connect];
   
    // Level Begin (Event #27)
    // For the purpose of this demo, we consider starting a match a Level Begin event.
    User *currentUser = [UserService.shared currentUser];
    long level = self.questLevel != nil ? self.questLevel.level : 0; // For quests use quest level, otherwise no level for challenges
    [AnalyticsService.shared.kApi levelBegin:[NSDate date] theAccountId:currentUser.userId theCharacterId:currentUser.name theCharacterLevel:currentUser.wizardLevel theShardId:0 theLevelId:level theX:0 theY:0 theZ:0 theAreaName:@""];
@]
Changed lines 231-233 from:
From MatchViewController Line 358: \\
[@ Sample coming soon@]
to:
From MatchViewController Line 376: \\
[@// Level End (Event #28)
    // For the purpose of this demo, we consider finishing a match a Level End event.
    long level = self.questLevel != nil ? self.questLevel.level : 0; // For quests use quest level, otherwise no level for challenges
    [AnalyticsService.shared.kApi levelEnd:[NSDate date] theAccountId:currentUser.userId theCharacterId:currentUser.name theCharacterLevel:currentUser.wizardLevel theShardId:0 theLevelId:level theX:0 theY:0 theZ:0 theAreaName:@""];
@]
Changed lines 257-259 from:
From MatchViewController.m Line 216: \\
[@ Sample coming soon@]
to:
From MatchViewController.m Line 227: \\
[@ // NPC Event (#31)
    // For the purpose of this demo, we consider it an NPC event when an AI Wizard is created. There is no max level, so we use an arbitrarily high number that would most likely never be achieved.
    [AnalyticsService.shared.kApi logNpcInteraction:[NSDate date] theAccountId:user.userId theCharacterId:user.name theShardId:0 npcEventName:@"NPC Spawned" npcEventType:@"Combat" npcId:npcId npcName:ai.wizard.name npcType:@"Enemy" theMinLevel:level.wizardLevel theMaxLevel:9999 theToughness:level.level  theToughnessEnum:level.name];
   
    Match * match = [[Match alloc] initWithMatchId:@"Quest" hostName:wizard.name currentWizard:wizard withAI:ai multiplayer:nil sync:nil];
@]
Changed lines 281-282 from:
[@ Sample coming soon@]
to:
[@if (isRemote) {
        [self notifyOpponent:challenge];
    }
   
    // Recruitment Send (Event #33)
    // For the purpose of this demo, we will consider a Recruitment Send event when a user challenges an opponent.
    [AnalyticsService.shared.kApi recruitmentSend:[NSDate date] sendAccId:user.userId sendCharId:user.name recvAccId:opponent.userId recvCharId:opponent.name theRecruitmentType:@"Invited By Another User"];
@]
Changed lines 306-307 from:
From ChallengeService.m Line 120, 128: \\
[@ Sample coming soon@]
to:
From ChallengeService.m Line 120: \\
[@- (void)acceptChallenge:(Challenge*)challenge {
    [AnalyticsService event:@"challenge-accept"];
    [self setChallenge:challenge status:ChallengeStatusAccepted];
   
    // Recruitment Receive (Event #34)
    // For the purpose of this demo, we will consider a Recruitment Receive event when a user accepts a challenge.
    [AnalyticsService.shared.kApi recruitmentReceive:[NSDate date] sendAccId:challenge.main.userId sendCharId:challenge.main.name recvAccId:challenge.opponent.userId recvCharId:challenge.opponent.name theRecruitmentType:@"Invited By Another User" theRecruitmentOutcome:@"Accepted"];
}
@]

'+'''Sample'''+' \\
From ChallengeService.m Line 128: \\
[@- (void)declineChallenge:(Challenge*)challenge {
    [self setChallenge:challenge status:ChallengeStatusDeclined];
   
    // Recruitment Receive (Event #34)
    // For the purpose of this demo, we will consider a Recruitment Receive event when a user declines a challenge.
    [AnalyticsService.shared.kApi recruitmentReceive:[NSDate date] sendAccId:challenge.main.userId sendCharId:challenge.main.name recvAccId:challenge.opponent.userId recvCharId:challenge.opponent.name theRecruitmentType:@"Invited By Another User" theRecruitmentOutcome:@"Declined"];
}
@]
Changed lines 14-15 from:
#Run XCode.  Click “Open Other” in the Recent projects window and select the '''WizardWar.xcworkspace''' file in the project root directory.
to:
#Run XCode.  Click “Open Other” in the Recent projects window and select the '''WizardWar.xcworkspace''' file in the project root directory. \\
\\
Added lines 31-33:

%right%[[#top|Back to Top]]
----
Changed lines 9-15 from:
1. If you do not have an Apple developer account, register at http://developer.apple.com/register. \\
2.
Download and install Xcode 5 from https://developer.apple.com/devcenter/ios or the App Store. \\
3.
Install the CocoaPods dependency manager.  From a Terminal window run: %Courier New%'''sudo gem install cocoapods''' \\
4.
Download the example project from https://bitbucket.org/ninja_metrics/katana-ios-integration-example. \\
5.
Open a Terminal window to the project root directory and download any missing dependencies by running: %Courier New%'''pod install''' \\
6.
Run XCode.  Click “Open Other” in the Recent projects window and select the '''WizardWar.xcworkspace''' file in the project root directory. \\
to:
#If you do not have an Apple developer account, register at http://developer.apple.com/register.
#Download and install Xcode 5 from https://developer.apple.com/devcenter/ios or the App Store.
#Install the CocoaPods dependency manager.  From a Terminal window run: %Courier New%'''sudo gem install cocoapods'''
#Download the example project from https://bitbucket.org/ninja_metrics/katana-ios-integration-example.
#Open a Terminal window to the project root directory and download any missing dependencies by running: %Courier New%'''pod install'''
#Run XCode.  Click “Open Other” in the Recent projects window and select the '''WizardWar.xcworkspace''' file in the project root directory.
Changed lines 21-29 from:
Katana API events can be called like so:
[-[AnalyticsService.shared.kAPI logSomeEvent:foo withParameter:bar];-]

For the timestamp parameter required by all events, we use the following constructor to create a new NSDate object initialized to the current UTC time:
[-[NSDate date]-]

For the account id and character id parameters required by most events, we use the uniquely generated "id" and user-defined "name" properties of the "User" object that may be already provided as a local variable or accessed via the UserService:
[-User *currentUser = [UserService.shared currentUser];-]
to:
Katana API events can be called like so:\\
'''
[AnalyticsService.shared.kAPI logSomeEvent:foo withParameter:bar];'''

For the timestamp parameter required by all events, we use the following constructor to create a new NSDate object initialized to the current UTC time:\\
'''
[NSDate date]'''

For the account id and character id parameters required by most events, we use the uniquely generated "id" and user-defined "name" properties of the "User" object that may be already provided as a local variable or accessed via the UserService:\\
'''
User *currentUser = [UserService.shared currentUser];'''
Changed lines 46-47 from:
From UserService.m Line 230:
to:
From UserService.m Line 230: \\
[@ Sample coming soon@]

Changed lines 62-63 from:
From AppDelegate.m Line 163, 190, 218:
to:
From AppDelegate.m Line 163, 190, 218: \\
[@ Sample coming soon@]

Changed lines 80-81 from:
From ProfileViewController.m Line 280:
to:
From ProfileViewController.m Line 280: \\
[@ Sample coming soon@]

Changed lines 100-101 from:
From UserService.m Line 216:
to:
From UserService.m Line 216: \\
[@ Sample coming soon@]

Changed lines 118-120 from:
From Combos.m Line 76:
*[--]
to:
From Combos.m Line 76: \\
[@ Sample coming soon@]
Changed lines 136-137 from:
From Match.m Line 653:
to:
From Match.m Line 653: \\
[@ Sample coming soon@]

Changed lines 152-153 from:
From MatchViewController.m Line 137:
to:
From MatchViewController.m Line 137: \\
[@ Sample coming soon@]

Changed lines 168-169 from:
From MatchViewController Line 358:
to:
From MatchViewController Line 358: \\
[@ Sample coming soon@]

Changed lines 191-192 from:
From MatchViewController.m Line 216:
to:
From MatchViewController.m Line 216: \\
[@ Sample coming soon@]

Changed lines 210-211 from:
From ChallengeService.m Line 190:
to:
From ChallengeService.m Line 190: \\
[@ Sample coming soon@]

Changed lines 230-231 from:
From ChallengeService.m Line 120, 128:
to:
From ChallengeService.m Line 120, 128: \\
[@ Sample coming soon@]

Changed lines 245-246 from:
From Match.m Line 237:
to:
From Match.m Line 237: \\
[@ Sample coming soon@]

Changed lines 260-261 from:
From MatchViewController Line 339:
to:
From MatchViewController Line 339: \\
[@ Sample coming soon@]

Changed lines 276-277 from:
From Match.m Line 571:
to:
From Match.m Line 571: \\
[@ Sample coming soon@]

Changed lines 291-292 from:
From MatchViewController Line 339:
to:
From MatchViewController Line 339: \\
[@ Sample coming soon@]

Changed lines 307-308 from:
From Match.m Line 566:
to:
From Match.m Line 566: \\
[@ Sample coming soon@]

Changed lines 324-325 from:
From MatchViewController.m Line 206, 345, 351:
to:
From MatchViewController.m Line 206, 345, 351: \\
[@ Sample coming soon@]

Changed lines 342-347 from:
From QuestService.m Line 80:

From SpellbookService.m Line 111:

From UserFriendService
.m Line 100:
to:
From QuestService.m Line 80: \\
[@ Sample coming soon@]

From SpellbookService
.m Line 111: \\
[@ Sample coming soon@]

From UserFriendService.m Line 100: \\
[@ Sample coming soon@]

Changed lines 368-369 from:
From MatchmakingViewController.m Line 863:
to:
From MatchmakingViewController.m Line 863: \\
[@ Sample coming soon@]

Changed lines 386-387 from:
From UserFriendService.m Line 84:
to:
From UserFriendService.m Line 84: \\
[@ Sample coming soon@]

Changed lines 404-405 from:
From MatchmakingViewController.m Line 465:
to:
From MatchmakingViewController.m Line 465: \\
[@ Sample coming soon@]

Changed lines 421-422 from:
From Match.m Line 522:
to:
From Match.m Line 522: \\
[@ Sample coming soon@]
Changed lines 1-4 from:
'+Getting Started+'\\
to:
[[#top]]

!!
'''Getting Started'''\\
Changed lines 9-16 from:
#If you do not have an Apple developer account, register at http://developer.apple.com/register.
#Download and install Xcode 5 from https://developer.apple.com/devcenter/ios or the App Store.
#Install the CocoaPods dependency manager.  From a Terminal window run:\\
%Courier New%'''sudo gem install cocoapods'''
#Download the example project from https://bitbucket.org/ninja_metrics/katana-ios-integration-example.
#Open a Terminal window to the project root directory and download any missing dependencies by running:\\
%Courier New%'''pod install'''
#Run XCode.  Click “Open Other” in the Recent projects window and select the '''WizardWar.xcworkspace''' file in the project root directory.
to:
1. If you do not have an Apple developer account, register at http://developer.apple.com/register. \\
2. Download and install Xcode 5 from https://developer.apple.com/devcenter/ios or the App Store. \\
3. Install the CocoaPods dependency manager.  From a Terminal window run: %Courier New%'''sudo gem install cocoapods''' \\
4. Download the example project from https://bitbucket.org/ninja_metrics/katana-ios-integration-example. \\
5. Open a Terminal window to the project root directory and download any missing dependencies by running: %Courier New%'''pod install''' \\
6. Run XCode.  Click “Open Other” in the Recent projects window and select the '''WizardWar.xcworkspace''' file in the project root directory. \\

!!'''Event Implementations'''\\

The following sections are the detailed notes for the implementation of various Katana API events.
The Katana iOS library was integrated into the AnalyticsService class under '''\WizardWar\Service'''. 

Katana API events can be called like so:
[-[AnalyticsService.shared.kAPI logSomeEvent:foo withParameter:bar];-]

For the timestamp parameter required by all events, we use the following constructor to create a new NSDate object initialized to the current UTC time:
[-[NSDate date]-]

For the account id and character id parameters required by most events, we use the uniquely generated "id" and user-defined "name" properties of the "User" object that may be already provided as a local variable or accessed via the UserService:
[-User *currentUser = [UserService.shared currentUser];-]

Since the game is not a complete virtual world with areas or locations we always use an empty string for the area name as well as "0" for area id, X, Y, and Z location parameters.  The game also lacks different instances or shards, so "0" is also used for shard id in all locations.  The string "iOS" is used for the platform parameter.

!!!!'''Login (Event ID #1) '''
There is no straightforward login process in this game for single or multiplayer.  Therefore, it will be considered a Login event when the attribute "currentUser" from the UserService is assigned a User object.  Also, a Login event is recorded when the application is brought back to the foreground after being minimized.

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| ACCOUNT ID || || The unique user id attribute of the User object ||
|| CHARACTER ID ||  || The user defined name attribute of the User object ||
|| SHARD ID || 0 || Zero since there's no notion of shards ||
|| PLATFORM || "iOS" || Denotes the application platform ||
|| AREA ID || 0 || Zero since there's no notion of areas ||
|| AREA NAME || "" || An empty string is used since there's no notion of areas ||

'+'''Sample'''+' \\
From UserService.m Line 230:

%right%[[#top|Back to Top]]
----

!!!!'''Logout (Event ID #2)'''
There is no straightforward logout process in this game for single or multiplayer.  Therefore, it will be considered a Logout event when the application is terminated or moved to the background.  Also by default, the iOS API wrapper uses the Logout event as a heartbeat to ping the Katana server on a regular interval.

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| ACCOUNT ID || || The unique user id attribute of the User object||
|| CHARACTER ID || || The user defined name attribute of the User object||

'+'''Sample'''+' \\
From AppDelegate.m Line 163, 190, 218:

%right%[[#top|Back to Top]]
----

!!!!'''Subscription Change (Event ID #3)'''
The game only has a free version and there is no notion of subscriptions or upgrading to a paid subscription.  However, initially a player is considered a "guest user" until the user connects their Facebook account with the game.  Therefore, it will be considered a Subscription Change event when the user is upgraded from a "guest user" after they connect their Facebook account.

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| SUBSCRIPTION STATUS || "Active" || Since the account is still active, only upgraded||
|| SUBSCRIPTION TYPE || "Premium" || Since it's not paid, but different than free||
|| SUBSCRIPTION VALUE || 0 || Zero since the game is free||
|| SUBSCRIPTION EXPIRATION TIMESTAMP || || There is no expiration, but for testing a date one year in the future is used||

'+'''Sample'''+' \\
From ProfileViewController.m Line 280:

%right%[[#top|Back to Top]]
----

!!!!'''Create Account (Event ID #9) '''
There is no process to create an account in this game.  However, the first time the application is launched, a user is created with a unique identifier for their device and a random name is chosen.  This unique identifier remains the same until the game is uninstalled. Therefore, it will be considered a Create Account event when the application is first launched and a new user with a unique identifier is created.

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| ACCOUNT TYPE || "Free" || The game is Free||
|| LANGUAGE || "en-US" || Ninja Metrics US English language code||
|| COUNTRY || "US" || Ninja Metrics United States country code||
|| GENDER || "N" || Since you cannot denote a gender in game settings||
|| DOB || || The game doesn't include DOB in game settings, so a dummy past date is used||
|| CURRENCY BALACE || 0 || Zero since there is no notion of currency||

'+'''Sample'''+' \\
From UserService.m Line 216:

%right%[[#top|Back to Top]]
----

!!!!'''Initialize Item (Event ID #15)'''
The game does not have items in the classic sense, but an appropriate substitution is the spells that wizards cast against each other.  Therefore, it will be considered an Initialize Item event when a player creates a Spell by moving their fingers in a particular pattern about the on screen Pentagram.

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| ITEM ID || || The randomly generated Spell id||
|| ITEM NAME || || The name of the Spell||
|| ITEM TYPE || "Weapons" || Since are used against other Wizards||
|| ITEM SEGMENT || "UGC" || Since the player creates the Spell||

'+'''Sample'''+' \\
From Combos.m Line 76:
*[--]

%right%[[#top|Back to Top]]
----

!!!!'''Item Used (Event ID #16)'''
Since spells will be the representation of items in this game, it will be considered an Item Used event when a player casts a spell against another player.

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| ITEM ID || || The randomly generated Spell id||
|| ITEM NAME || || The name of the Spell||
|| ITEM Count || 0 || Zero since a Spell can be cast unlimited times||
|| ITEM SEGMENT || "UGC" || Since the player creates the Spell||

'+'''Sample'''+' \\
From Match.m Line 653:

%right%[[#top|Back to Top]]
----

!!!!'''Level Begin (Event ID #27)'''
In the game, a match begins when a player starts a quest or a multiplayer duel.  It will be considered a Level Begin event when a new match, either a quest or duel, begins.

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| LEVEL ID || || The current Quest level or 0 for duels||
|| CHARACTER LEVEL || || The player's Wizard level||

'+'''Sample'''+' \\
From MatchViewController.m Line 137:

%right%[[#top|Back to Top]]
----

!!!!'''Level End (Event ID #28)'''
Similar to a Level Begin event, it will be considered a Level End event when a match, either a quest or duel, ends.

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| LEVEL ID || || The current Quest level or 0 for duels||
|| CHARACTER LEVEL || || The player's Wizard level||

'+'''Sample'''+' \\
From MatchViewController Line 358:

%right%[[#top|Back to Top]]
----

!!!!'''Non-Player Character (Event ID #31)'''
In the game, a player can play quest levels that are duels against AI based wizards.  It will be considered a Non-Player Character when an enemy AI wizard is spawned at the beginning of a quest. This initializes the NPC in the dimension table for the other NPC related events.

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| NPC EVENT NAME || "NPC Spawned" || Since this is the NPC initialization event||
|| NPC EVENT TYPE || "Combat" || Since players battle the NPC in a Quest||
|| NPC ID || || The Quest level is used since each NPC is unique to a Quest level||
|| NPC NAME || || The AI based Wizard name||
|| NPC TYPE || "Enemy" || Since the player always fights the NPC in a Quest||
|| MIN LEVEL || || The Wizard level required to play this Quest||
|| MAX LEVEL ||  || There is no max level, so we use an arbitrarily high number that is unlikely to be achieved. Due to the current iOS API library implementation, values not required by the API or that use default values are not taken into account.  Therefore where applicable values do not exist we must use placeholder values that might not make perfect sense in the current context.||
|| TOUGHNESS || || The Quest level||
|| TOUGHNESS ENUM || || The Quest level name||

'+'''Sample'''+' \\
From MatchViewController.m Line 216:

%right%[[#top|Back to Top]]
----

!!!!'''Recruitment Send (Event ID #33)'''
In the game, a player can challenge an opponent to a duel.  The act of challenging another player to a duel will be considered a Recruitment Send event.

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| SEND ACCOUNT ID || || The user id of the player who initiated the duel challenge||
|| SEND CHARACTER ID || || The wizard name of the player who initiated the duel challenge||
|| RECEIVER ACCOUNT ID || || The user id of the player who was challenged to a duel||
|| RECEIVER CHARACTER ID || || The wizard name of the player who was challenged to a duel||
|| RECRUITMENT TYPE || "Invited By Another User" || Since one player challenges the other||

'+'''Sample'''+' \\
From ChallengeService.m Line 190:

%right%[[#top|Back to Top]]
----

!!!!'''Recruitment Receive Action (Event ID #34)'''
In the game, a player can respond to a duel challenge sent by another player.  The act of the player responding to a duel challenge will be considered a Recruitment Send event.

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| SEND ACCOUNT ID || || The user id of the player who initiated the duel challenge||
|| SEND CHARACTER ID || || The wizard name of the player who initiated the duel challenge||
|| RECEIVER ACCOUNT ID || || The user id of the player who was challenged to a duel||
|| RECEIVER CHARACTER ID || || The wizard name of the player who was challenged to a duel||
|| RECRUITMENT TYPE ||  "Invited By Another User" || Since one player challenges the other||
|| RECRUITMENT OUTCOME || "Accepted" or "Declined" || Depending the receiver's response||

'+'''Sample'''+' \\
From ChallengeService.m Line 120, 128:

%right%[[#top|Back to Top]]
----

!!!!'''Begin Combat (Event ID #21)'''
In the game, a quest is a match with an NPC AI based wizard.  It will be considered a Begin Combat event when a quest's match status is changed to "Playing" and combat has begun.

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| NPC ID ||  || The Quest level is used since each NPC is unique to a Quest level||

'+'''Sample'''+' \\
From Match.m Line 237:

%right%[[#top|Back to Top]]
----

!!!!'''End Combat (Event ID #22)'''
Similar to the Begin Combat event, it will be considered an End Combat event when a quest's match status is "Finished" and combat has ceased.

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| NPC ID ||  || The Quest level is used since each NPC is unique to a Quest level||

'+'''Sample'''+' \\
From MatchViewController Line 339:

%right%[[#top|Back to Top]]
----

!!!!'''Kill NPC (Event ID #23)'''
It will be considered a Kill NPC event when a player has won a quest by defeating its NPC AI based wizard.

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| CHARACTER LEVEL || || The player's Wizard level||
|| NPC ID || || The Quest level is used since each NPC is unique to a Quest level||

'+'''Sample'''+' \\
From Match.m Line 571:

%right%[[#top|Back to Top]]
----

!!!!'''Player Versus Player Duel (Event ID #25)'''
It will be considered a Player Versus Player Duel event when a multiplayer match ends.

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| WIN FLAG: || YES or NO || Depending on the outcome of the duel||

'+'''Sample'''+' \\
From MatchViewController Line 339:

%right%[[#top|Back to Top]]
----

!!!!'''Player Death (Event ID #26)'''
It will be considered a Player Death event when an NPC AI kills the player's wizard and the player loses the quest.

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| NPC ID ||  || The Quest level is used since each NPC is unique to a Quest level||
|| DEATH TYPE || "NA" || NA, since all deaths are the treated the same||

'+'''Sample'''+' \\
From Match.m Line 566:

%right%[[#top|Back to Top]]
----

!!!!'''Challenge (Event ID #32)'''
In the game, a challenge could be considered a quest level where the player duels an NPC AI based wizard.  It will be considered a Challenge event when a player chooses to play a quest level, leaves the quest level, or completes the quest level.

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| CHALLENGE ID ||  || The Quest level name||
|| CHALLENGE TYPE || "Kill An NPC or Multiple NPCs" || Since all Quests are duels with NPCs||
|| CHALLENGE STATUS ||  "Accepted", "Completed", or "Abandoned" || Depending on player action||

'+'''Sample'''+' \\
From MatchViewController.m Line 206, 345, 351:

%right%[[#top|Back to Top]]
----

!!!!'''Reward (Event ID #49)'''
It will be considered a Reward event when the player's wizard level is increased as a result of completing a quest, casting spells, or winning a duel against another player who has a greater wizard level than their own.

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| REWARD TYPE || 0 || Zero since only recording one type of Reward||
|| REWARD ID || "Wizard Level" || Since the only recorded Reward is gaining a Wizard level||
|| ITEM TYPE || 0 || Zero since no item is being rewarded||
|| REWARD COUNT || || The player's new Wizard level||

'+'''Sample'''+' \\
From QuestService.m Line 80:

From SpellbookService.m Line 111:

From UserFriendService.m Line 100:

%right%[[#top|Back to Top]]
----

!!!!'''Off-Game-Interaction Sender (Event ID #7)'''
The game allows a player to send a download link to others for the game via Facebook by posting on their Facebook friends' walls.  It will be considered an OGI Sender event when the player sends a message about the game to one of their Facebook friends.

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| SENDER ACCOUNT ID || || The player's user id who shared to Facebook||
|| SENDER ACCOUNT NAME || || The player's wizard name who shared to Facebook||
|| RECEIVER ACCOUNT ID || || The Facebook id of the receiving friend||
|| RECEIVER ACCOUNT NAME || || The Facebook id of the receiving friend||
|| OGI LOCATION || "Facebook" || ||
|| OGI CATEGORY || "Posts on Social Media" || ||

'+'''Sample'''+' \\
From MatchmakingViewController.m Line 863:

%right%[[#top|Back to Top]]
----

!!!!'''Friend Addition (Event ID #43)'''
When the first duel between two players ends, they are now considered "Frenemies" and will always appear in their Lobby, even if they are logged out.  It will be considered a Friend Addition Event when the first duel ends between two players and they become "Frenemies".

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| SENDER ACCOUNT ID ||  || The player's user id who initiated the duel||
|| SENDER ACCOUNT NAME || || The player's wizard name who initiated the duel||
|| RECEIVER ACCOUNT ID ||  || The player's user id who was challenged to the duel||
|| RECEIVER ACCOUNT NAME || || The player's wizard name who was challenged to the duel||

'+'''Sample'''+' \\
From UserFriendService.m Line 84:

%right%[[#top|Back to Top]]
----

!!!!'''Friend Deletion (Event ID #44)'''
After a player becomes the user's "Frenemy", the user can remove them as a "Frenemy" by swiping their entry on the Lobby list and pressing the "Defrenemy" button.  It will be considered a Friend Deletion event when a user removes another player as a "Frenemy".

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| SENDER ACCOUNT ID ||  || The player's user id who removed the "Frenemy"||
|| SENDER ACCOUNT NAME || || The player's wizard name who removed the "Frenemy"||
|| RECEIVER ACCOUNT ID || || The player's user id who was removed as a "Frenemy"||
|| RECEIVER ACCOUNT NAME || || The player's wizard name who was removed as a "Frenemy"||

'+'''Sample'''+' \\
From MatchmakingViewController.m Line 465:

%right%[[#top|Back to Top]]
----

!!!!'''Custom Slot (Event ID #54)'''
The Katana API has an empty slot to allow for a Custom event to be recorded that is unique to the particular application.  The custom event recorded here is a "Block".  During a duel a player can cast a spell that prevents them from being hit by a spell cast by an opposing player or NPC.

'+'''Parameters'''+'
|| border=1 rules=rows frame=hsides
||! Parameter ||! Value ||! Note ||
|| CUSTOM ACTION ||  "Block" || || 
|| CUSTOM ACTION TYPE ||  "Spell Interaction" || ||
|| CUSTOM ACTION VALUE || 0 || Zero since there is only one state for a Block ||

'+'''Sample'''+' \\
From Match.m Line 522:

%right%[[#top|Back to Top]]
----
January 14, 2014, at 10:58 PM by Russ Harvey - Add Getting Started section
Changed lines 1-13 from:
Placeholder
to:
'+Getting Started+'\\
The iOS integration example is based on the open-source multiplayer game Wizard War.

In order to build and run this project, you’ll need a system running OS X.

#If you do not have an Apple developer account, register at http://developer.apple.com/register.
#Download and install Xcode 5 from https://developer.apple.com/devcenter/ios or the App Store.
#Install the CocoaPods dependency manager.  From a Terminal window run:\\
%Courier New%'''sudo gem install cocoapods'''
#Download the example project from https://bitbucket.org/ninja_metrics/katana-ios-integration-example.
#Open a Terminal window to the project root directory and download any missing dependencies by running:\\
%Courier New%'''pod install'''
#Run XCode.  Click “Open Other” in the Recent projects window and select the '''WizardWar.xcworkspace''' file in the project root directory.
Added line 1:
Placeholder