Merge pull request #141 from OwenBrotherwood/master

iOS HockeyKit / QuincyKit (HockeyApp) update
This commit is contained in:
Shazron Abdullah
2011-09-13 11:41:07 -07:00
234 changed files with 33540 additions and 495 deletions

View File

@@ -1,6 +1,5 @@
//
// HockeyApp.h
// jnsog
//
// Created by Owen Brotherwood on 8/24/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
@@ -15,6 +14,7 @@
- (void) init:(NSArray*)arguments withDict:(NSDictionary*)options;
- (void) checkForUpdate:(NSArray*)arguments withDict:(NSDictionary*)options;
- (void) showUpdateView:(NSArray*)arguments withDict:(NSDictionary*)options;
- (void) isUpdateAvailable:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
- (void) initiateAppDownload:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
- (void) crashTest:(NSArray*)arguments withDict:(NSDictionary*)options;

View File

@@ -0,0 +1,42 @@
// HockeyApp.js
// Created by Owen Brotherwood on 8/24/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
var HockeyApp = (function() {
checkForUpdate = function() {
PhoneGap.exec("HockeyApp.checkForUpdate");
},
showUpdateView = function(){
PhoneGap.exec("HockeyApp.showUpdateView");
},
isUpdateAvailable = function(cb) { // provide a function that can be called back with result: ''/1
PhoneGap.exec("HockeyApp.isUpdateAvailable", GetFunctionName(cb));
},
initiateAppDownload = function(cb){ // provide a function that can be called back with result: ''/1
PhoneGap.exec("HockeyApp.initiateAppDownload", GetFunctionName(cb));
},
crashTest = function() {
PhoneGap.exec("HockeyApp.crashTest");
},
init = function(args){ // args.appIdentifier
PhoneGap.exec("HockeyApp.init", args);
};
return{
checkForUpdate : checkForUpdate, // causes a requester if new software is found
showUpdateView: showUpdateView, // the HockeyKit Update View
isUpdateAvailable : isUpdateAvailable, // checks if new software is available
initiateAppDownload : initiateAppDownload, // causes an requester for download of new software
crashTest : crashTest, // cause crash to test QuincyKit
init : init // called before use with the appIdentifier
};
})();

View File

@@ -10,24 +10,27 @@
#import "BWQuincyManager.h"
@implementation HockeyApp
- (void) init:(NSArray*)arguments withDict:(NSDictionary*)options
{
// collect appIdentifier from JavaScript or just hardcode it here.
{
// collect appIdentifier from JavaScript or just hardcode it here.
NSString* appIdentifier = [options valueForKey:@"appIdentifier"];
[[BWHockeyManager sharedHockeyManager] setAppIdentifier:appIdentifier];
[[BWQuincyManager sharedQuincyManager] setAppIdentifier:appIdentifier];
[[BWQuincyManager sharedQuincyManager] setAppIdentifier:appIdentifier];
}
// produces a requester with HockeyApp default defaults
// produces a requester with HockeyApp
- (void) checkForUpdate:(NSArray*)arguments withDict:(NSDictionary*)options
{
[[BWHockeyManager sharedHockeyManager] checkForUpdate];
}
- (void) showUpdateView:(NSArray*)arguments withDict:(NSDictionary*)options
{
[[BWHockeyManager sharedHockeyManager] showUpdateView];
}
- (void) isUpdateAvailable:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
{
NSString *jsString;
@@ -61,4 +64,4 @@
@end

View File

@@ -10,21 +10,11 @@ I chose the name HockeyApp as it contains the meaning of both kits...
Implements the most basic needs in the HockeyKit, via javascript :)
There is a demo based on the v1.0.0 PhoneGap default Xcode (4.02) Project.
The necessary js, m and h files are in the demo.
Demos based on the v1.0.0 PhoneGap default Xcode (4.02) Project.
The projectfiles contains a script, makeIT, that creates a directory structure and collects HockeyKit and QuincyKit.
Also, not that the HockeyApp.js is copied into the www folders by the build script (otherwise I will have multiple instances of the js ...)
The demo was created with these steps for using the commercial service, the Open Source is just as easy but there is a 1 month free trial of the service and is a lot easier (I have tried both methods)
- Get PhoneGap from http://www.phonegap.com and install for iOS
- Try the PhoneGap default Xcode Project (note that one has to build once, then add files by referance www (folder is in the project) and run again (this is something in PhoneGap v1.0.0 that may be fixed latter in PhoneGap)
- Get the "Hockey AppKit-iOS-latest.zip" from https://github.com/TheRealKerni/HockeyKit/downloads and add the files (I did this using group and copy)
- Place the js in www folder, the .h and .m in the PhoneGap/Plugins folder
- Add "HockeyApp" in the Plugins for PhoneGap.plist (HockeyApp string HockeyApp).
- Some html/js alterations in the index.html to call the js routines
- Remember to alter App ID in html or Plugin/HockeyApp.m
To test one has to upload a version to HockeyApp.net, then bump the version and upload again. Try the App and see that it prompts for upgrade.
There is a fine little button that one can push that causes instant crash. On next start of App it will ask if crash data can be sent.
https://github.com/TheRealKerni/HockeyKit/wiki/iOS-Client-API
- good list of possible functions to implement
@@ -32,3 +22,10 @@ https://github.com/TheRealKerni/HockeyKit/wiki/iOS-Client-API
https://github.com/TheRealKerni/QuincyKit/wiki
- hmm, have to find the same as HockeyKit ...
Get going ...
1 Install PhoneGap Version 1.0
2 Run the makeIT in a directory for your work
3 Find the demo project you would like to see
4 Run the demo
Note: the App ID in these demo's will stop at some stage as it is from a one month free trial.

View File

@@ -0,0 +1,2 @@
.DS_Store
build/

View File

@@ -0,0 +1 @@
Uses Jquery Mobile

View File

@@ -0,0 +1,5 @@
project.xcworkspace/*
project.xcworkspace
xcuserdata/*
xcuserdata

View File

@@ -0,0 +1,686 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
2E09C52D141F387000F1004C /* BWQuincyManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E09C529141F387000F1004C /* BWQuincyManager.m */; };
2E09C52E141F387000F1004C /* CrashReporter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2E09C52A141F387000F1004C /* CrashReporter.framework */; };
2E09C52F141F387000F1004C /* LICENSE.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2E09C52B141F387000F1004C /* LICENSE.txt */; };
2E09C530141F387000F1004C /* Quincy.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 2E09C52C141F387000F1004C /* Quincy.bundle */; };
2E09C55C141F388300F1004C /* BWApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E09C537141F388300F1004C /* BWApp.m */; };
2E09C55D141F388300F1004C /* BWGlobal.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E09C539141F388300F1004C /* BWGlobal.m */; };
2E09C55E141F388300F1004C /* BWHockeyManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E09C53B141F388300F1004C /* BWHockeyManager.m */; };
2E09C55F141F388300F1004C /* BWHockeySettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E09C53D141F388300F1004C /* BWHockeySettingsViewController.m */; };
2E09C560141F388300F1004C /* BWHockeyViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E09C53F141F388300F1004C /* BWHockeyViewController.m */; };
2E09C561141F388300F1004C /* NSString+HockeyAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E09C542141F388300F1004C /* NSString+HockeyAdditions.m */; };
2E09C562141F388300F1004C /* PSAppStoreHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E09C544141F388300F1004C /* PSAppStoreHeader.m */; };
2E09C563141F388300F1004C /* PSStoreButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E09C546141F388300F1004C /* PSStoreButton.m */; };
2E09C564141F388300F1004C /* PSWebTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E09C548141F388300F1004C /* PSWebTableViewCell.m */; };
2E09C565141F388300F1004C /* UIImage+HockeyAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E09C54A141F388300F1004C /* UIImage+HockeyAdditions.m */; };
2E09C566141F388300F1004C /* Hockey.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 2E09C54B141F388300F1004C /* Hockey.bundle */; };
2E09C567141F388300F1004C /* JSONKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E09C553141F388300F1004C /* JSONKit.m */; };
2E09C568141F388300F1004C /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 2E09C554141F388300F1004C /* README.md */; };
2E09C569141F388300F1004C /* README.mkdown in Resources */ = {isa = PBXBuildFile; fileRef = 2E09C555141F388300F1004C /* README.mkdown */; };
2E1F2AB1141E190500B8CA28 /* README in Resources */ = {isa = PBXBuildFile; fileRef = 2E1F2AB0141E190500B8CA28 /* README */; };
2E90989F141E395600240444 /* www in Resources */ = {isa = PBXBuildFile; fileRef = 2E90989E141E395600240444 /* www */; };
2E9E862A1419EE020099031E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2E9E86291419EE020099031E /* Foundation.framework */; };
2E9E862C1419EE020099031E /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2E9E862B1419EE020099031E /* UIKit.framework */; };
2E9E862E1419EE020099031E /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2E9E862D1419EE020099031E /* CoreGraphics.framework */; };
2E9E86301419EE020099031E /* AddressBook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2E9E862F1419EE020099031E /* AddressBook.framework */; };
2E9E86321419EE020099031E /* AddressBookUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2E9E86311419EE020099031E /* AddressBookUI.framework */; };
2E9E86341419EE020099031E /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2E9E86331419EE020099031E /* AudioToolbox.framework */; };
2E9E86361419EE020099031E /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2E9E86351419EE020099031E /* AVFoundation.framework */; };
2E9E86381419EE020099031E /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2E9E86371419EE020099031E /* CoreLocation.framework */; };
2E9E863A1419EE020099031E /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2E9E86391419EE020099031E /* MediaPlayer.framework */; };
2E9E863C1419EE020099031E /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2E9E863B1419EE020099031E /* QuartzCore.framework */; };
2E9E863E1419EE020099031E /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2E9E863D1419EE020099031E /* SystemConfiguration.framework */; };
2E9E86401419EE020099031E /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2E9E863F1419EE020099031E /* MobileCoreServices.framework */; };
2E9E86421419EE020099031E /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2E9E86411419EE020099031E /* CoreMedia.framework */; };
2E9E86481419EE020099031E /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2E9E86461419EE020099031E /* InfoPlist.strings */; };
2E9E864A1419EE020099031E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E9E86491419EE020099031E /* main.m */; };
2E9E864D1419EE030099031E /* PhoneGap.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2E9E864C1419EE030099031E /* PhoneGap.framework */; };
2E9E86521419EE030099031E /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2E9E86501419EE030099031E /* Localizable.strings */; };
2E9E86561419EE030099031E /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2E9E86541419EE030099031E /* Localizable.strings */; };
2E9E86591419EE030099031E /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 2E9E86581419EE030099031E /* icon.png */; };
2E9E865B1419EE030099031E /* icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2E9E865A1419EE030099031E /* icon@2x.png */; };
2E9E865D1419EE030099031E /* icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 2E9E865C1419EE030099031E /* icon-72.png */; };
2E9E86601419EE030099031E /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 2E9E865F1419EE030099031E /* Default.png */; };
2E9E86621419EE030099031E /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2E9E86611419EE030099031E /* Default@2x.png */; };
2E9E86641419EE030099031E /* Capture.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 2E9E86631419EE030099031E /* Capture.bundle */; };
2E9E86661419EE030099031E /* PhoneGap.plist in Resources */ = {isa = PBXBuildFile; fileRef = 2E9E86651419EE030099031E /* PhoneGap.plist */; };
2E9E866A1419EE040099031E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E9E86691419EE040099031E /* AppDelegate.m */; };
2EE4A820141E0ABE004B75B3 /* HockeyApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 2EE4A81F141E0ABE004B75B3 /* HockeyApp.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
2E09C56B141F388500F1004C /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2E09C54D141F388300F1004C /* HockeyLib.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = D2AAC07E0554694100DB518D;
remoteInfo = HockeyLib;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
2E09C528141F387000F1004C /* BWQuincyManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BWQuincyManager.h; sourceTree = "<group>"; };
2E09C529141F387000F1004C /* BWQuincyManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BWQuincyManager.m; sourceTree = "<group>"; };
2E09C52A141F387000F1004C /* CrashReporter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = CrashReporter.framework; sourceTree = "<group>"; };
2E09C52B141F387000F1004C /* LICENSE.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE.txt; sourceTree = "<group>"; };
2E09C52C141F387000F1004C /* Quincy.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Quincy.bundle; sourceTree = "<group>"; };
2E09C536141F388300F1004C /* BWApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BWApp.h; sourceTree = "<group>"; };
2E09C537141F388300F1004C /* BWApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BWApp.m; sourceTree = "<group>"; };
2E09C538141F388300F1004C /* BWGlobal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BWGlobal.h; sourceTree = "<group>"; };
2E09C539141F388300F1004C /* BWGlobal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BWGlobal.m; sourceTree = "<group>"; };
2E09C53A141F388300F1004C /* BWHockeyManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BWHockeyManager.h; sourceTree = "<group>"; };
2E09C53B141F388300F1004C /* BWHockeyManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BWHockeyManager.m; sourceTree = "<group>"; };
2E09C53C141F388300F1004C /* BWHockeySettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BWHockeySettingsViewController.h; sourceTree = "<group>"; };
2E09C53D141F388300F1004C /* BWHockeySettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BWHockeySettingsViewController.m; sourceTree = "<group>"; };
2E09C53E141F388300F1004C /* BWHockeyViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BWHockeyViewController.h; sourceTree = "<group>"; };
2E09C53F141F388300F1004C /* BWHockeyViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BWHockeyViewController.m; sourceTree = "<group>"; };
2E09C541141F388300F1004C /* NSString+HockeyAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+HockeyAdditions.h"; sourceTree = "<group>"; };
2E09C542141F388300F1004C /* NSString+HockeyAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+HockeyAdditions.m"; sourceTree = "<group>"; };
2E09C543141F388300F1004C /* PSAppStoreHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSAppStoreHeader.h; sourceTree = "<group>"; };
2E09C544141F388300F1004C /* PSAppStoreHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PSAppStoreHeader.m; sourceTree = "<group>"; };
2E09C545141F388300F1004C /* PSStoreButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSStoreButton.h; sourceTree = "<group>"; };
2E09C546141F388300F1004C /* PSStoreButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PSStoreButton.m; sourceTree = "<group>"; };
2E09C547141F388300F1004C /* PSWebTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSWebTableViewCell.h; sourceTree = "<group>"; };
2E09C548141F388300F1004C /* PSWebTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PSWebTableViewCell.m; sourceTree = "<group>"; };
2E09C549141F388300F1004C /* UIImage+HockeyAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+HockeyAdditions.h"; sourceTree = "<group>"; };
2E09C54A141F388300F1004C /* UIImage+HockeyAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+HockeyAdditions.m"; sourceTree = "<group>"; };
2E09C54B141F388300F1004C /* Hockey.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Hockey.bundle; sourceTree = "<group>"; };
2E09C54D141F388300F1004C /* HockeyLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = HockeyLib.xcodeproj; sourceTree = "<group>"; };
2E09C550141F388300F1004C /* HockeyLib_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HockeyLib_Prefix.pch; sourceTree = "<group>"; };
2E09C552141F388300F1004C /* JSONKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONKit.h; sourceTree = "<group>"; };
2E09C553141F388300F1004C /* JSONKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSONKit.m; sourceTree = "<group>"; };
2E09C554141F388300F1004C /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = "<group>"; };
2E09C555141F388300F1004C /* README.mkdown */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.mkdown; sourceTree = "<group>"; };
2E1F2AB0141E190500B8CA28 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README; path = ../pluginHockeyApp/README; sourceTree = "<group>"; };
2E90989E141E395600240444 /* www */ = {isa = PBXFileReference; lastKnownFileType = folder; path = www; sourceTree = "<group>"; };
2E9E86251419EE020099031E /* jqmHockeyApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = jqmHockeyApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
2E9E86291419EE020099031E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
2E9E862B1419EE020099031E /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
2E9E862D1419EE020099031E /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
2E9E862F1419EE020099031E /* AddressBook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBook.framework; path = System/Library/Frameworks/AddressBook.framework; sourceTree = SDKROOT; };
2E9E86311419EE020099031E /* AddressBookUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBookUI.framework; path = System/Library/Frameworks/AddressBookUI.framework; sourceTree = SDKROOT; };
2E9E86331419EE020099031E /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
2E9E86351419EE020099031E /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
2E9E86371419EE020099031E /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
2E9E86391419EE020099031E /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; };
2E9E863B1419EE020099031E /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
2E9E863D1419EE020099031E /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
2E9E863F1419EE020099031E /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
2E9E86411419EE020099031E /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
2E9E86451419EE020099031E /* jqmHockeyApp-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "jqmHockeyApp-Info.plist"; sourceTree = "<group>"; };
2E9E86471419EE020099031E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
2E9E86491419EE020099031E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
2E9E864B1419EE020099031E /* jqmHockeyApp-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "jqmHockeyApp-Prefix.pch"; sourceTree = "<group>"; };
2E9E864C1419EE030099031E /* PhoneGap.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PhoneGap.framework; path = /Users/Shared/PhoneGap/Frameworks/PhoneGap.framework; sourceTree = "<absolute>"; };
2E9E86511419EE030099031E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = Resources/en.lproj/Localizable.strings; sourceTree = "<group>"; };
2E9E86551419EE030099031E /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = Resources/es.lproj/Localizable.strings; sourceTree = "<group>"; };
2E9E86581419EE030099031E /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon.png; path = Resources/icons/icon.png; sourceTree = "<group>"; };
2E9E865A1419EE030099031E /* icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "icon@2x.png"; path = "Resources/icons/icon@2x.png"; sourceTree = "<group>"; };
2E9E865C1419EE030099031E /* icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "icon-72.png"; path = "Resources/icons/icon-72.png"; sourceTree = "<group>"; };
2E9E865F1419EE030099031E /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = Resources/splash/Default.png; sourceTree = "<group>"; };
2E9E86611419EE030099031E /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default@2x.png"; path = "Resources/splash/Default@2x.png"; sourceTree = "<group>"; };
2E9E86631419EE030099031E /* Capture.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = Capture.bundle; path = Resources/Capture.bundle; sourceTree = "<group>"; };
2E9E86651419EE030099031E /* PhoneGap.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = PhoneGap.plist; sourceTree = "<group>"; };
2E9E86681419EE040099031E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Classes/AppDelegate.h; sourceTree = "<group>"; };
2E9E86691419EE040099031E /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = Classes/AppDelegate.m; sourceTree = "<group>"; };
2E9E866C1419EE040099031E /* README */ = {isa = PBXFileReference; lastKnownFileType = text; name = README; path = Plugins/README; sourceTree = "<group>"; };
2EE4A81E141E0ABE004B75B3 /* HockeyApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HockeyApp.h; path = ../../HockeyApp.h; sourceTree = "<group>"; };
2EE4A81F141E0ABE004B75B3 /* HockeyApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HockeyApp.m; path = ../../HockeyApp.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
2E9E861F1419EE020099031E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
2E9E862A1419EE020099031E /* Foundation.framework in Frameworks */,
2E9E862C1419EE020099031E /* UIKit.framework in Frameworks */,
2E9E862E1419EE020099031E /* CoreGraphics.framework in Frameworks */,
2E9E86301419EE020099031E /* AddressBook.framework in Frameworks */,
2E9E86321419EE020099031E /* AddressBookUI.framework in Frameworks */,
2E9E86341419EE020099031E /* AudioToolbox.framework in Frameworks */,
2E9E86361419EE020099031E /* AVFoundation.framework in Frameworks */,
2E9E86381419EE020099031E /* CoreLocation.framework in Frameworks */,
2E9E863A1419EE020099031E /* MediaPlayer.framework in Frameworks */,
2E9E863C1419EE020099031E /* QuartzCore.framework in Frameworks */,
2E9E863E1419EE020099031E /* SystemConfiguration.framework in Frameworks */,
2E9E86401419EE020099031E /* MobileCoreServices.framework in Frameworks */,
2E9E86421419EE020099031E /* CoreMedia.framework in Frameworks */,
2E9E864D1419EE030099031E /* PhoneGap.framework in Frameworks */,
2E09C52E141F387000F1004C /* CrashReporter.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
2E9E86221419EE020099031E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
2E09C527141F387000F1004C /* iOS */ = {
isa = PBXGroup;
children = (
2E09C528141F387000F1004C /* BWQuincyManager.h */,
2E09C529141F387000F1004C /* BWQuincyManager.m */,
2E09C52A141F387000F1004C /* CrashReporter.framework */,
2E09C52B141F387000F1004C /* LICENSE.txt */,
2E09C52C141F387000F1004C /* Quincy.bundle */,
);
name = iOS;
path = ../../../../HockeyAppKit/QuincyKit/client/iOS;
sourceTree = "<group>";
};
2E09C531141F388300F1004C /* iOS */ = {
isa = PBXGroup;
children = (
2E09C536141F388300F1004C /* BWApp.h */,
2E09C537141F388300F1004C /* BWApp.m */,
2E09C538141F388300F1004C /* BWGlobal.h */,
2E09C539141F388300F1004C /* BWGlobal.m */,
2E09C53A141F388300F1004C /* BWHockeyManager.h */,
2E09C53B141F388300F1004C /* BWHockeyManager.m */,
2E09C53C141F388300F1004C /* BWHockeySettingsViewController.h */,
2E09C53D141F388300F1004C /* BWHockeySettingsViewController.m */,
2E09C53E141F388300F1004C /* BWHockeyViewController.h */,
2E09C53F141F388300F1004C /* BWHockeyViewController.m */,
2E09C540141F388300F1004C /* Helper */,
2E09C54B141F388300F1004C /* Hockey.bundle */,
2E09C54C141F388300F1004C /* HockeyLib */,
2E09C551141F388300F1004C /* JSON */,
2E09C555141F388300F1004C /* README.mkdown */,
);
name = iOS;
path = ../../../../HockeyAppKit/HockeyKit/client/iOS;
sourceTree = "<group>";
};
2E09C540141F388300F1004C /* Helper */ = {
isa = PBXGroup;
children = (
2E09C541141F388300F1004C /* NSString+HockeyAdditions.h */,
2E09C542141F388300F1004C /* NSString+HockeyAdditions.m */,
2E09C543141F388300F1004C /* PSAppStoreHeader.h */,
2E09C544141F388300F1004C /* PSAppStoreHeader.m */,
2E09C545141F388300F1004C /* PSStoreButton.h */,
2E09C546141F388300F1004C /* PSStoreButton.m */,
2E09C547141F388300F1004C /* PSWebTableViewCell.h */,
2E09C548141F388300F1004C /* PSWebTableViewCell.m */,
2E09C549141F388300F1004C /* UIImage+HockeyAdditions.h */,
2E09C54A141F388300F1004C /* UIImage+HockeyAdditions.m */,
);
path = Helper;
sourceTree = "<group>";
};
2E09C54C141F388300F1004C /* HockeyLib */ = {
isa = PBXGroup;
children = (
2E09C54D141F388300F1004C /* HockeyLib.xcodeproj */,
2E09C550141F388300F1004C /* HockeyLib_Prefix.pch */,
);
path = HockeyLib;
sourceTree = "<group>";
};
2E09C54E141F388300F1004C /* Products */ = {
isa = PBXGroup;
children = (
2E09C56C141F388500F1004C /* libHockeyLib.a */,
);
name = Products;
sourceTree = "<group>";
};
2E09C551141F388300F1004C /* JSON */ = {
isa = PBXGroup;
children = (
2E09C552141F388300F1004C /* JSONKit.h */,
2E09C553141F388300F1004C /* JSONKit.m */,
2E09C554141F388300F1004C /* README.md */,
);
path = JSON;
sourceTree = "<group>";
};
2E9E86171419EE010099031E = {
isa = PBXGroup;
children = (
87DF3EA7141E577A00636605 /* HockeyAppKit */,
2E90989E141E395600240444 /* www */,
2E1F2AB0141E190500B8CA28 /* README */,
2E9E86431419EE020099031E /* jqmHockeyApp */,
2E9E86281419EE020099031E /* Frameworks */,
2E9E86261419EE020099031E /* Products */,
);
sourceTree = "<group>";
};
2E9E86261419EE020099031E /* Products */ = {
isa = PBXGroup;
children = (
2E9E86251419EE020099031E /* jqmHockeyApp.app */,
);
name = Products;
sourceTree = "<group>";
};
2E9E86281419EE020099031E /* Frameworks */ = {
isa = PBXGroup;
children = (
2E9E86291419EE020099031E /* Foundation.framework */,
2E9E862B1419EE020099031E /* UIKit.framework */,
2E9E862D1419EE020099031E /* CoreGraphics.framework */,
2E9E862F1419EE020099031E /* AddressBook.framework */,
2E9E86311419EE020099031E /* AddressBookUI.framework */,
2E9E86331419EE020099031E /* AudioToolbox.framework */,
2E9E86351419EE020099031E /* AVFoundation.framework */,
2E9E86371419EE020099031E /* CoreLocation.framework */,
2E9E86391419EE020099031E /* MediaPlayer.framework */,
2E9E863B1419EE020099031E /* QuartzCore.framework */,
2E9E863D1419EE020099031E /* SystemConfiguration.framework */,
2E9E863F1419EE020099031E /* MobileCoreServices.framework */,
2E9E86411419EE020099031E /* CoreMedia.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
2E9E86431419EE020099031E /* jqmHockeyApp */ = {
isa = PBXGroup;
children = (
2E9E864C1419EE030099031E /* PhoneGap.framework */,
2E9E864E1419EE030099031E /* Resources */,
2E9E86671419EE040099031E /* Classes */,
2E9E866B1419EE040099031E /* Plugins */,
2E9E86441419EE020099031E /* Supporting Files */,
);
path = jqmHockeyApp;
sourceTree = "<group>";
};
2E9E86441419EE020099031E /* Supporting Files */ = {
isa = PBXGroup;
children = (
2E9E86451419EE020099031E /* jqmHockeyApp-Info.plist */,
2E9E86461419EE020099031E /* InfoPlist.strings */,
2E9E86491419EE020099031E /* main.m */,
2E9E864B1419EE020099031E /* jqmHockeyApp-Prefix.pch */,
2E9E86651419EE030099031E /* PhoneGap.plist */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
2E9E864E1419EE030099031E /* Resources */ = {
isa = PBXGroup;
children = (
2E9E86631419EE030099031E /* Capture.bundle */,
2E9E864F1419EE030099031E /* en.lproj */,
2E9E86531419EE030099031E /* es.lproj */,
2E9E86571419EE030099031E /* icons */,
2E9E865E1419EE030099031E /* splash */,
);
name = Resources;
sourceTree = "<group>";
};
2E9E864F1419EE030099031E /* en.lproj */ = {
isa = PBXGroup;
children = (
2E9E86501419EE030099031E /* Localizable.strings */,
);
name = en.lproj;
sourceTree = "<group>";
};
2E9E86531419EE030099031E /* es.lproj */ = {
isa = PBXGroup;
children = (
2E9E86541419EE030099031E /* Localizable.strings */,
);
name = es.lproj;
sourceTree = "<group>";
};
2E9E86571419EE030099031E /* icons */ = {
isa = PBXGroup;
children = (
2E9E86581419EE030099031E /* icon.png */,
2E9E865A1419EE030099031E /* icon@2x.png */,
2E9E865C1419EE030099031E /* icon-72.png */,
);
name = icons;
sourceTree = "<group>";
};
2E9E865E1419EE030099031E /* splash */ = {
isa = PBXGroup;
children = (
2E9E865F1419EE030099031E /* Default.png */,
2E9E86611419EE030099031E /* Default@2x.png */,
);
name = splash;
sourceTree = "<group>";
};
2E9E86671419EE040099031E /* Classes */ = {
isa = PBXGroup;
children = (
2E9E86681419EE040099031E /* AppDelegate.h */,
2E9E86691419EE040099031E /* AppDelegate.m */,
);
name = Classes;
sourceTree = "<group>";
};
2E9E866B1419EE040099031E /* Plugins */ = {
isa = PBXGroup;
children = (
2EE4A81E141E0ABE004B75B3 /* HockeyApp.h */,
2EE4A81F141E0ABE004B75B3 /* HockeyApp.m */,
2E9E866C1419EE040099031E /* README */,
);
name = Plugins;
sourceTree = "<group>";
};
87DF3EA7141E577A00636605 /* HockeyAppKit */ = {
isa = PBXGroup;
children = (
87DF3EA9141E57A200636605 /* QuincyKit */,
87DF3EA8141E579000636605 /* HockeyKit */,
);
name = HockeyAppKit;
sourceTree = "<group>";
};
87DF3EA8141E579000636605 /* HockeyKit */ = {
isa = PBXGroup;
children = (
2E09C531141F388300F1004C /* iOS */,
);
name = HockeyKit;
sourceTree = "<group>";
};
87DF3EA9141E57A200636605 /* QuincyKit */ = {
isa = PBXGroup;
children = (
2E09C527141F387000F1004C /* iOS */,
);
name = QuincyKit;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
2E9E86241419EE020099031E /* jqmHockeyApp */ = {
isa = PBXNativeTarget;
buildConfigurationList = 2E9E866F1419EE040099031E /* Build configuration list for PBXNativeTarget "jqmHockeyApp" */;
buildPhases = (
2E9E861E1419EE020099031E /* Sources */,
2E9E861F1419EE020099031E /* Frameworks */,
2E9E86201419EE020099031E /* Resources */,
2E9E86211419EE020099031E /* Sources */,
2E9E86221419EE020099031E /* Frameworks */,
2E9E86231419EE020099031E /* ShellScript */,
);
buildRules = (
);
dependencies = (
);
name = jqmHockeyApp;
productName = jqmHockeyApp;
productReference = 2E9E86251419EE020099031E /* jqmHockeyApp.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
2E9E86191419EE010099031E /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0420;
};
buildConfigurationList = 2E9E861C1419EE010099031E /* Build configuration list for PBXProject "jqmHockeyApp" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
es,
);
mainGroup = 2E9E86171419EE010099031E;
productRefGroup = 2E9E86261419EE020099031E /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 2E09C54E141F388300F1004C /* Products */;
ProjectRef = 2E09C54D141F388300F1004C /* HockeyLib.xcodeproj */;
},
);
projectRoot = "";
targets = (
2E9E86241419EE020099031E /* jqmHockeyApp */,
);
};
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
2E09C56C141F388500F1004C /* libHockeyLib.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libHockeyLib.a;
remoteRef = 2E09C56B141F388500F1004C /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
2E9E86201419EE020099031E /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
2E9E86481419EE020099031E /* InfoPlist.strings in Resources */,
2E9E86521419EE030099031E /* Localizable.strings in Resources */,
2E9E86561419EE030099031E /* Localizable.strings in Resources */,
2E9E86591419EE030099031E /* icon.png in Resources */,
2E9E865B1419EE030099031E /* icon@2x.png in Resources */,
2E9E865D1419EE030099031E /* icon-72.png in Resources */,
2E9E86601419EE030099031E /* Default.png in Resources */,
2E9E86621419EE030099031E /* Default@2x.png in Resources */,
2E9E86641419EE030099031E /* Capture.bundle in Resources */,
2E9E86661419EE030099031E /* PhoneGap.plist in Resources */,
2E1F2AB1141E190500B8CA28 /* README in Resources */,
2E90989F141E395600240444 /* www in Resources */,
2E09C52F141F387000F1004C /* LICENSE.txt in Resources */,
2E09C530141F387000F1004C /* Quincy.bundle in Resources */,
2E09C566141F388300F1004C /* Hockey.bundle in Resources */,
2E09C568141F388300F1004C /* README.md in Resources */,
2E09C569141F388300F1004C /* README.mkdown in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
2E9E86231419EE020099031E /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
shellScript = "cp ../HockeyApp.js www/lib/phonegap/plugins/\n\n\t\t\t\t\t\t\t\tif [ ! -d \"$PROJECT_DIR/www\" ] ; then\n\t\t\t\t\t\t\t\t\tcp -R /Users/Shared/PhoneGap/Frameworks/PhoneGap.framework/www \"$PROJECT_DIR\"\n\t\t\t\t\t\t\t\tfi\n\t\t\t\t\t\t\t\t# detect www folder reference in project, if missing, print warning\n\t\t\t\t\t\t\t\tgrep \"{isa = PBXFileReference; lastKnownFileType = folder; path = www; sourceTree = \\\"<group>\\\"; };\" \"$PROJECT_DIR/$PROJECT_NAME.xcodeproj/project.pbxproj\"\n\t\t\t\t\t\t\t\trc=$? \n\t\t\t\t\t\t\t\tif [ $rc != 0 ] ; then\n\t\t\t\t\t\t\t\techo -e \"warning: Missing - Add $PROJECT_DIR/www as a folder reference in your project. Just drag and drop the folder into your project, in Xcode 4.\" 1>&2\n\t\t\t\t\t\t\t\tfi\t\t\t\t\t\t\t";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
2E9E861E1419EE020099031E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
2E9E864A1419EE020099031E /* main.m in Sources */,
2E9E866A1419EE040099031E /* AppDelegate.m in Sources */,
2EE4A820141E0ABE004B75B3 /* HockeyApp.m in Sources */,
2E09C52D141F387000F1004C /* BWQuincyManager.m in Sources */,
2E09C55C141F388300F1004C /* BWApp.m in Sources */,
2E09C55D141F388300F1004C /* BWGlobal.m in Sources */,
2E09C55E141F388300F1004C /* BWHockeyManager.m in Sources */,
2E09C55F141F388300F1004C /* BWHockeySettingsViewController.m in Sources */,
2E09C560141F388300F1004C /* BWHockeyViewController.m in Sources */,
2E09C561141F388300F1004C /* NSString+HockeyAdditions.m in Sources */,
2E09C562141F388300F1004C /* PSAppStoreHeader.m in Sources */,
2E09C563141F388300F1004C /* PSStoreButton.m in Sources */,
2E09C564141F388300F1004C /* PSWebTableViewCell.m in Sources */,
2E09C565141F388300F1004C /* UIImage+HockeyAdditions.m in Sources */,
2E09C567141F388300F1004C /* JSONKit.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
2E9E86211419EE020099031E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
2E9E86461419EE020099031E /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
2E9E86471419EE020099031E /* en */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
2E9E86501419EE030099031E /* Localizable.strings */ = {
isa = PBXVariantGroup;
children = (
2E9E86511419EE030099031E /* en */,
);
name = Localizable.strings;
sourceTree = "<group>";
};
2E9E86541419EE030099031E /* Localizable.strings */ = {
isa = PBXVariantGroup;
children = (
2E9E86551419EE030099031E /* es */,
);
name = Localizable.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
2E9E866D1419EE040099031E /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_VERSION = com.apple.compilers.llvmgcc42;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 4.0;
PROVISIONING_PROFILE = "";
SDKROOT = iphoneos;
};
name = Debug;
};
2E9E866E1419EE040099031E /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_VERSION = com.apple.compilers.llvmgcc42;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 4.0;
PROVISIONING_PROFILE = "";
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
2E9E86701419EE040099031E /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = YES;
COPY_PHASE_STRIP = NO;
FRAMEWORK_SEARCH_PATHS = (
/Users/Shared/PhoneGap/Frameworks,
"\"$(SRCROOT)/../../../../HockeyAppKit/QuincyKit/client/iOS\"",
);
GCC_DYNAMIC_NO_PIC = NO;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "jqmHockeyApp/jqmHockeyApp-Prefix.pch";
GCC_PREPROCESSOR_DEFINITIONS = "PHONEGAP_FRAMEWORK=YES";
INFOPLIST_FILE = "jqmHockeyApp/jqmHockeyApp-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 4.0;
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
};
name = Debug;
};
2E9E86711419EE040099031E /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = YES;
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
FRAMEWORK_SEARCH_PATHS = (
/Users/Shared/PhoneGap/Frameworks,
"\"$(SRCROOT)/../../../../HockeyAppKit/QuincyKit/client/iOS\"",
);
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "jqmHockeyApp/jqmHockeyApp-Prefix.pch";
GCC_PREPROCESSOR_DEFINITIONS = "PHONEGAP_FRAMEWORK=YES";
INFOPLIST_FILE = "jqmHockeyApp/jqmHockeyApp-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 4.0;
PRODUCT_NAME = "$(TARGET_NAME)";
VALIDATE_PRODUCT = YES;
WRAPPER_EXTENSION = app;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
2E9E861C1419EE010099031E /* Build configuration list for PBXProject "jqmHockeyApp" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2E9E866D1419EE040099031E /* Debug */,
2E9E866E1419EE040099031E /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
2E9E866F1419EE040099031E /* Build configuration list for PBXNativeTarget "jqmHockeyApp" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2E9E86701419EE040099031E /* Debug */,
2E9E86711419EE040099031E /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 2E9E86191419EE010099031E /* Project object */;
}

View File

@@ -0,0 +1,6 @@
project.xcworkspace/*
project.xcworkspace
xcuserdata/*
xcuserdata
build

View File

@@ -0,0 +1,29 @@
//
// AppDelegate.h
// jqmHockeyApp
//
// Created by Owen Brotherwood on 9/9/11.
// Copyright __MyCompanyName__ 2011. All rights reserved.
//
#import <UIKit/UIKit.h>
#ifdef PHONEGAP_FRAMEWORK
#import <PhoneGap/PhoneGapDelegate.h>
#else
#import "PhoneGapDelegate.h"
#endif
@interface AppDelegate : PhoneGapDelegate {
NSString* invokeString;
}
// invoke string is passed to your app on launch, this is only valid if you
// edit jqmHockeyApp.plist to add a protocol
// a simple tutorial can be found here :
// http://iphonedevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html
@property (copy) NSString* invokeString;
@end

View File

@@ -0,0 +1,112 @@
//
// AppDelegate.m
// jqmHockeyApp
//
// Created by Owen Brotherwood on 9/9/11.
// Copyright __MyCompanyName__ 2011. All rights reserved.
//
#import "AppDelegate.h"
#ifdef PHONEGAP_FRAMEWORK
#import <PhoneGap/PhoneGapViewController.h>
#else
#import "PhoneGapViewController.h"
#endif
@implementation AppDelegate
@synthesize invokeString;
- (id) init
{
/** If you need to do any extra app-specific initialization, you can do it here
* -jm
**/
return [super init];
}
/**
* This is main kick off after the app inits, the views and Settings are setup here. (preferred - iOS4 and up)
*/
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSArray *keyArray = [launchOptions allKeys];
if ([launchOptions objectForKey:[keyArray objectAtIndex:0]]!=nil)
{
NSURL *url = [launchOptions objectForKey:[keyArray objectAtIndex:0]];
self.invokeString = [url absoluteString];
NSLog(@"jqmHockeyApp launchOptions = %@",url);
}
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
// this happens while we are running ( in the background, or from within our own app )
// only valid if jqmHockeyApp.plist specifies a protocol to handle
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
// must call super so all plugins will get the notification, and their handlers will be called
// super also calls into javascript global function 'handleOpenURL'
return [super application:application handleOpenURL:url];
}
-(id) getCommandInstance:(NSString*)className
{
/** You can catch your own commands here, if you wanted to extend the gap: protocol, or add your
* own app specific protocol to it. -jm
**/
return [super getCommandInstance:className];
}
/**
Called when the webview finishes loading. This stops the activity view and closes the imageview
*/
- (void)webViewDidFinishLoad:(UIWebView *)theWebView
{
// only valid if jqmHockeyApp.plist specifies a protocol to handle
if(self.invokeString)
{
// this is passed before the deviceready event is fired, so you can access it in js when you receive deviceready
NSString* jsString = [NSString stringWithFormat:@"var invokeString = \"%@\";", self.invokeString];
[theWebView stringByEvaluatingJavaScriptFromString:jsString];
}
return [ super webViewDidFinishLoad:theWebView ];
}
- (void)webViewDidStartLoad:(UIWebView *)theWebView
{
return [ super webViewDidStartLoad:theWebView ];
}
/**
* Fail Loading With Error
* Error - If the webpage failed to load display an error with the reason.
*/
- (void)webView:(UIWebView *)theWebView didFailLoadWithError:(NSError *)error
{
return [ super webView:theWebView didFailLoadWithError:error ];
}
/**
* Start Loading Request
* This is where most of the magic happens... We take the request(s) and process the response.
* From here we can re direct links and other protocalls to different internal methods.
*/
- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
return [ super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType ];
}
- (BOOL) execute:(InvokedUrlCommand*)command
{
return [ super execute:command];
}
- (void)dealloc
{
[ super dealloc ];
}
@end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,937 @@
/*
* Author: Andreas Linde <mail@andreaslinde.de>
* Kent Sutherland
*
* Copyright (c) 2011 Andreas Linde & Kent Sutherland.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#import <CrashReporter/CrashReporter.h>
#import <SystemConfiguration/SystemConfiguration.h>
#import <UIKit/UIKit.h>
#import "BWQuincyManager.h"
#include <sys/sysctl.h>
#include <inttypes.h> //needed for PRIx64 macro
NSBundle *quincyBundle(void) {
static NSBundle* bundle = nil;
if (!bundle) {
NSString* path = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:kQuincyBundleName];
bundle = [[NSBundle bundleWithPath:path] retain];
}
return bundle;
}
NSString *BWQuincyLocalize(NSString *stringToken) {
if ([BWQuincyManager sharedQuincyManager].languageStyle == nil)
return NSLocalizedStringFromTableInBundle(stringToken, @"Quincy", quincyBundle(), @"");
else {
NSString *alternate = [NSString stringWithFormat:@"Quincy%@", [BWQuincyManager sharedQuincyManager].languageStyle];
return NSLocalizedStringFromTableInBundle(stringToken, alternate, quincyBundle(), @"");
}
}
@interface BWQuincyManager ()
- (void)startManager;
- (void)showCrashStatusMessage;
- (void)handleCrashReport;
- (void)_cleanCrashReports;
- (void)_checkForFeedbackStatus;
- (void)_performSendingCrashReports;
- (void)_sendCrashReports;
- (NSString *)_crashLogStringForReport:(PLCrashReport *)report;
- (void)_postXML:(NSString*)xml toURL:(NSURL*)url;
- (NSString *)_getDevicePlatform;
- (BOOL)hasNonApprovedCrashReports;
- (BOOL)hasPendingCrashReport;
@end
@implementation BWQuincyManager
@synthesize delegate = _delegate;
@synthesize submissionURL = _submissionURL;
@synthesize showAlwaysButton = _showAlwaysButton;
@synthesize feedbackActivated = _feedbackActivated;
@synthesize autoSubmitCrashReport = _autoSubmitCrashReport;
@synthesize autoSubmitDeviceUDID = _autoSubmitDeviceUDID;
@synthesize languageStyle = _languageStyle;
@synthesize appIdentifier = _appIdentifier;
+ (BWQuincyManager *)sharedQuincyManager {
static BWQuincyManager *quincyManager = nil;
if (quincyManager == nil) {
quincyManager = [[BWQuincyManager alloc] init];
}
return quincyManager;
}
- (id) init {
if ((self = [super init])) {
_serverResult = CrashReportStatusUnknown;
_crashIdenticalCurrentVersion = YES;
_crashData = nil;
_urlConnection = nil;
_submissionURL = nil;
_responseData = nil;
_appIdentifier = nil;
_sendingInProgress = NO;
_languageStyle = nil;
self.delegate = nil;
self.feedbackActivated = NO;
self.showAlwaysButton = NO;
self.autoSubmitCrashReport = NO;
self.autoSubmitDeviceUDID = NO;
NSString *testValue = [[NSUserDefaults standardUserDefaults] stringForKey:kQuincyKitAnalyzerStarted];
if (testValue) {
_analyzerStarted = [[NSUserDefaults standardUserDefaults] integerForKey:kQuincyKitAnalyzerStarted];
} else {
_analyzerStarted = 0;
}
testValue = nil;
testValue = [[NSUserDefaults standardUserDefaults] stringForKey:kQuincyKitActivated];
if (testValue) {
_crashReportActivated = [[NSUserDefaults standardUserDefaults] boolForKey:kQuincyKitActivated];
} else {
_crashReportActivated = YES;
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithBool:YES] forKey:kQuincyKitActivated];
}
if ([[NSUserDefaults standardUserDefaults] stringForKey:kAutomaticallySendCrashReports]) {
self.autoSubmitCrashReport = [[NSUserDefaults standardUserDefaults] boolForKey: kAutomaticallySendCrashReports];
}
if (_crashReportActivated) {
_crashFiles = [[NSMutableArray alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
_crashesDir = [[NSString stringWithFormat:@"%@", [[paths objectAtIndex:0] stringByAppendingPathComponent:@"/crashes/"]] retain];
NSFileManager *fm = [NSFileManager defaultManager];
if (![fm fileExistsAtPath:_crashesDir]) {
NSDictionary *attributes = [NSDictionary dictionaryWithObject: [NSNumber numberWithUnsignedLong: 0755] forKey: NSFilePosixPermissions];
NSError *theError = NULL;
[fm createDirectoryAtPath:_crashesDir withIntermediateDirectories: YES attributes: attributes error: &theError];
}
PLCrashReporter *crashReporter = [PLCrashReporter sharedReporter];
NSError *error = NULL;
// Check if we previously crashed
if ([crashReporter hasPendingCrashReport]) {
[self handleCrashReport];
}
// Enable the Crash Reporter
if (![crashReporter enableCrashReporterAndReturnError: &error])
NSLog(@"Warning: Could not enable crash reporter: %@", error);
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(startManager) name:BWQuincyNetworkBecomeReachable object:nil];
}
}
return self;
}
- (void) dealloc {
self.delegate = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self name:BWQuincyNetworkBecomeReachable object:nil];
[_languageStyle release];
[_submissionURL release];
_submissionURL = nil;
[_appIdentifier release];
_appIdentifier = nil;
[_urlConnection cancel];
[_urlConnection release];
_urlConnection = nil;
[_crashData release];
[_crashesDir release];
[_crashFiles release];
[super dealloc];
}
#pragma mark -
#pragma mark setter
- (void)setSubmissionURL:(NSString *)anSubmissionURL {
if (_submissionURL != anSubmissionURL) {
[_submissionURL release];
_submissionURL = [anSubmissionURL copy];
}
[self performSelector:@selector(startManager) withObject:nil afterDelay:1.0f];
}
- (void)setAppIdentifier:(NSString *)anAppIdentifier {
if (_appIdentifier != anAppIdentifier) {
[_appIdentifier release];
_appIdentifier = [anAppIdentifier copy];
}
[self setSubmissionURL:@"https://beta.hockeyapp.net/"];
}
#pragma mark -
#pragma mark private methods
// begin the startup process
- (void)startManager {
if (!_sendingInProgress && [self hasPendingCrashReport]) {
_sendingInProgress = YES;
if (!self.autoSubmitCrashReport && [self hasNonApprovedCrashReports]) {
NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:BWQuincyLocalize(@"CrashDataFoundTitle"), appName]
message:[NSString stringWithFormat:BWQuincyLocalize(@"CrashDataFoundDescription"), appName]
delegate:self
cancelButtonTitle:BWQuincyLocalize(@"CrashDontSendReport")
otherButtonTitles:BWQuincyLocalize(@"CrashSendReport"), nil];
if ([self isShowingAlwaysButton]) {
[alertView addButtonWithTitle:BWQuincyLocalize(@"CrashSendReportAlways")];
}
[alertView setTag: QuincyKitAlertTypeSend];
[alertView show];
[alertView release];
} else {
[self _sendCrashReports];
}
}
}
- (BOOL)hasNonApprovedCrashReports {
NSDictionary *approvedCrashReports = [[NSUserDefaults standardUserDefaults] dictionaryForKey: kApprovedCrashReports];
if (!approvedCrashReports || [approvedCrashReports count] == 0) return YES;
for (NSUInteger i=0; i < [_crashFiles count]; i++) {
NSString *filename = [_crashFiles objectAtIndex:i];
if (![approvedCrashReports objectForKey:filename]) return YES;
}
return NO;
}
- (BOOL)hasPendingCrashReport {
if (_crashReportActivated) {
NSFileManager *fm = [NSFileManager defaultManager];
if ([_crashFiles count] == 0 && [fm fileExistsAtPath:_crashesDir]) {
NSString *file = nil;
NSError *error = NULL;
NSDirectoryEnumerator *dirEnum = [fm enumeratorAtPath: _crashesDir];
while ((file = [dirEnum nextObject])) {
NSDictionary *fileAttributes = [fm attributesOfItemAtPath:[_crashesDir stringByAppendingPathComponent:file] error:&error];
if ([[fileAttributes objectForKey:NSFileSize] intValue] > 0) {
[_crashFiles addObject:file];
}
}
}
if ([_crashFiles count] > 0) {
return YES;
} else
return NO;
} else
return NO;
}
- (void) showCrashStatusMessage {
UIAlertView *alertView;
if (_serverResult >= CrashReportStatusAssigned &&
_crashIdenticalCurrentVersion) {
// show some feedback to the user about the crash status
NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
switch (_serverResult) {
case CrashReportStatusAssigned:
alertView = [[UIAlertView alloc] initWithTitle: [NSString stringWithFormat:BWQuincyLocalize(@"CrashResponseTitle"), appName ]
message: [NSString stringWithFormat:BWQuincyLocalize(@"CrashResponseNextRelease"), appName]
delegate: self
cancelButtonTitle: BWQuincyLocalize(@"CrashResponseTitleOK")
otherButtonTitles: nil];
break;
case CrashReportStatusSubmitted:
alertView = [[UIAlertView alloc] initWithTitle: [NSString stringWithFormat:BWQuincyLocalize(@"CrashResponseTitle"), appName ]
message: [NSString stringWithFormat:BWQuincyLocalize(@"CrashResponseWaitingApple"), appName]
delegate: self
cancelButtonTitle: BWQuincyLocalize(@"CrashResponseTitleOK")
otherButtonTitles: nil];
break;
case CrashReportStatusAvailable:
alertView = [[UIAlertView alloc] initWithTitle: [NSString stringWithFormat:BWQuincyLocalize(@"CrashResponseTitle"), appName ]
message: [NSString stringWithFormat:BWQuincyLocalize(@"CrashResponseAvailable"), appName]
delegate: self
cancelButtonTitle: BWQuincyLocalize(@"CrashResponseTitleOK")
otherButtonTitles: nil];
break;
default:
alertView = nil;
break;
}
if (alertView != nil) {
[alertView setTag: QuincyKitAlertTypeFeedback];
[alertView show];
[alertView release];
}
}
}
#pragma mark -
#pragma mark UIAlertView Delegate
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if ([alertView tag] == QuincyKitAlertTypeSend) {
switch (buttonIndex) {
case 0:
_sendingInProgress = NO;
[self _cleanCrashReports];
break;
case 1:
[self _sendCrashReports];
break;
case 2:
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:kAutomaticallySendCrashReports];
[self _sendCrashReports];
break;
}
}
}
#pragma mark -
#pragma mark NSXMLParser Delegate
#pragma mark NSXMLParser
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
if (qName) {
elementName = qName;
}
if ([elementName isEqualToString:@"result"]) {
_contentOfProperty = [NSMutableString string];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if (qName) {
elementName = qName;
}
// open source implementation
if ([elementName isEqualToString: @"result"]) {
if ([_contentOfProperty intValue] > _serverResult) {
_serverResult = (CrashReportStatus)[_contentOfProperty intValue];
} else {
CrashReportStatus errorcode = (CrashReportStatus)[_contentOfProperty intValue];
NSLog(@"CrashReporter ended in error code: %i", errorcode);
}
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if (_contentOfProperty) {
// If the current element is one whose content we care about, append 'string'
// to the property that holds the content of the current element.
if (string != nil) {
[_contentOfProperty appendString:string];
}
}
}
#pragma mark -
#pragma mark Private
- (NSString *)_getOSVersionBuild {
size_t size = 0;
NSString *osBuildVersion = nil;
sysctlbyname("kern.osversion", NULL, &size, NULL, 0);
char *answer = (char*)malloc(size);
int result = sysctlbyname("kern.osversion", answer, &size, NULL, 0);
if (result >= 0) {
osBuildVersion = [NSString stringWithCString:answer encoding: NSUTF8StringEncoding];
}
return osBuildVersion;
}
- (NSString *)_getDevicePlatform {
size_t size = 0;
sysctlbyname("hw.machine", NULL, &size, NULL, 0);
char *answer = (char*)malloc(size);
sysctlbyname("hw.machine", answer, &size, NULL, 0);
NSString *platform = [NSString stringWithCString:answer encoding: NSUTF8StringEncoding];
free(answer);
return platform;
}
- (void)_performSendingCrashReports {
NSMutableDictionary *approvedCrashReports = [NSMutableDictionary dictionaryWithDictionary:[[NSUserDefaults standardUserDefaults] dictionaryForKey: kApprovedCrashReports]];
NSFileManager *fm = [NSFileManager defaultManager];
NSError *error = NULL;
NSString *userid = @"";
NSString *contact = @"";
NSString *description = @"";
if (self.autoSubmitDeviceUDID) {
userid = [[UIDevice currentDevice] uniqueIdentifier];
} else if (self.delegate != nil && [self.delegate respondsToSelector:@selector(crashReportUserID)]) {
userid = [self.delegate crashReportUserID];
}
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(crashReportContact)]) {
contact = [self.delegate crashReportContact];
}
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(crashReportDescription)]) {
description = [self.delegate crashReportDescription];
}
NSMutableString *crashes = nil;
_crashIdenticalCurrentVersion = NO;
for (NSUInteger i=0; i < [_crashFiles count]; i++) {
NSString *filename = [_crashesDir stringByAppendingPathComponent:[_crashFiles objectAtIndex:i]];
NSData *crashData = [NSData dataWithContentsOfFile:filename];
if ([crashData length] > 0) {
PLCrashReport *report = [[[PLCrashReport alloc] initWithData:crashData error:&error] autorelease];
if (report == nil) {
NSLog(@"Could not parse crash report");
continue;
}
NSString *crashLogString = [self _crashLogStringForReport:report];
if ([report.applicationInfo.applicationVersion compare:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]] == NSOrderedSame) {
_crashIdenticalCurrentVersion = YES;
}
if (crashes == nil) {
crashes = [NSMutableString string];
}
[crashes appendFormat:@"<crash><applicationname>%s</applicationname><bundleidentifier>%@</bundleidentifier><systemversion>%@</systemversion><platform>%@</platform><senderversion>%@</senderversion><version>%@</version><userid>%@</userid><contact>%@</contact><description><![CDATA[%@]]></description><log><![CDATA[%@]]></log></crash>",
[[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleExecutable"] UTF8String],
report.applicationInfo.applicationIdentifier,
[[UIDevice currentDevice] systemVersion],
[self _getDevicePlatform],
[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"],
report.applicationInfo.applicationVersion,
userid,
contact,
description,
crashLogString];
// store this crash report as user approved, so if it fails it will retry automatically
[approvedCrashReports setObject:[NSNumber numberWithBool:YES] forKey:[_crashFiles objectAtIndex:i]];
} else {
// we cannot do anything with this report, so delete it
[fm removeItemAtPath:filename error:&error];
}
}
[[NSUserDefaults standardUserDefaults] setObject:approvedCrashReports forKey:kApprovedCrashReports];
[[NSUserDefaults standardUserDefaults] synchronize];
if (crashes != nil) {
[self _postXML:[NSString stringWithFormat:@"<crashes>%@</crashes>", crashes]
toURL:[NSURL URLWithString:self.submissionURL]];
}
}
- (void)_cleanCrashReports {
NSError *error = NULL;
NSFileManager *fm = [NSFileManager defaultManager];
for (NSUInteger i=0; i < [_crashFiles count]; i++) {
[fm removeItemAtPath:[_crashesDir stringByAppendingPathComponent:[_crashFiles objectAtIndex:i]] error:&error];
}
[_crashFiles removeAllObjects];
[[NSUserDefaults standardUserDefaults] setObject:nil forKey:kApprovedCrashReports];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)_sendCrashReports {
// send it to the next runloop
[self performSelector:@selector(_performSendingCrashReports) withObject:nil afterDelay:0.0f];
}
- (NSString *)_crashLogStringForReport:(PLCrashReport *)report {
NSMutableString *xmlString = [NSMutableString string];
/* Header */
boolean_t lp64;
/* Map to apple style OS nane */
const char *osName;
switch (report.systemInfo.operatingSystem) {
case PLCrashReportOperatingSystemiPhoneOS:
osName = "iPhone OS";
break;
case PLCrashReportOperatingSystemiPhoneSimulator:
osName = "Mac OS X";
break;
default:
osName = "iPhone OS";
break;
}
/* Map to Apple-style code type */
NSString *codeType;
switch (report.systemInfo.architecture) {
case PLCrashReportArchitectureARM:
codeType = @"ARM (Native)";
lp64 = false;
break;
case PLCrashReportArchitectureX86_32:
codeType = @"X86";
lp64 = false;
break;
case PLCrashReportArchitectureX86_64:
codeType = @"X86-64";
lp64 = true;
break;
case PLCrashReportArchitecturePPC:
codeType = @"PPC";
lp64 = false;
break;
default:
codeType = @"ARM (Native)";
lp64 = false;
break;
}
[xmlString appendString:@"Incident Identifier: [TODO]\n"];
[xmlString appendString:@"CrashReporter Key: [TODO]\n"];
/* Application and process info */
{
NSString *unknownString = @"???";
NSString *processName = unknownString;
NSString *processId = unknownString;
NSString *processPath = unknownString;
NSString *parentProcessName = unknownString;
NSString *parentProcessId = unknownString;
/* Process information was not available in earlier crash report versions */
if (report.hasProcessInfo) {
/* Process Name */
if (report.processInfo.processName != nil)
processName = report.processInfo.processName;
/* PID */
processId = [[NSNumber numberWithUnsignedInteger: report.processInfo.processID] stringValue];
/* Process Path */
if (report.processInfo.processPath != nil)
processPath = report.processInfo.processPath;
/* Parent Process Name */
if (report.processInfo.parentProcessName != nil)
parentProcessName = report.processInfo.parentProcessName;
/* Parent Process ID */
parentProcessId = [[NSNumber numberWithUnsignedInteger: report.processInfo.parentProcessID] stringValue];
}
[xmlString appendFormat: @"Process: %@ [%@]\n", processName, processId];
[xmlString appendFormat: @"Path: %@\n", processPath];
[xmlString appendFormat: @"Identifier: %@\n", report.applicationInfo.applicationIdentifier];
[xmlString appendFormat: @"Version: %@\n", report.applicationInfo.applicationVersion];
[xmlString appendFormat: @"Code Type: %@\n", codeType];
[xmlString appendFormat: @"Parent Process: %@ [%@]\n", parentProcessName, parentProcessId];
}
[xmlString appendString:@"\n"];
/* System info */
[xmlString appendFormat:@"Date/Time: %s\n", [[report.systemInfo.timestamp description] UTF8String]];
NSString *buildNumber = [self _getOSVersionBuild];
if (buildNumber) {
[xmlString appendFormat:@"OS Version: %s %s (%s)\n", osName, [report.systemInfo.operatingSystemVersion UTF8String], [buildNumber UTF8String]];
} else {
[xmlString appendFormat:@"OS Version: %s %s\n", osName, [report.systemInfo.operatingSystemVersion UTF8String]];
}
[xmlString appendString:@"Report Version: 104\n"];
[xmlString appendString:@"\n"];
/* Exception code */
[xmlString appendFormat:@"Exception Type: %s\n", [report.signalInfo.name UTF8String]];
[xmlString appendFormat:@"Exception Codes: %@ at 0x%" PRIx64 "\n", report.signalInfo.code, report.signalInfo.address];
for (PLCrashReportThreadInfo *thread in report.threads) {
if (thread.crashed) {
[xmlString appendFormat: @"Crashed Thread: %ld\n", (long) thread.threadNumber];
break;
}
}
[xmlString appendString:@"\n"];
if (report.hasExceptionInfo) {
[xmlString appendString:@"Application Specific Information:\n"];
[xmlString appendFormat: @"*** Terminating app due to uncaught exception '%@', reason: '%@'\n",
report.exceptionInfo.exceptionName, report.exceptionInfo.exceptionReason];
[xmlString appendString:@"\n"];
}
/* Threads */
PLCrashReportThreadInfo *crashed_thread = nil;
for (PLCrashReportThreadInfo *thread in report.threads) {
if (thread.crashed) {
[xmlString appendFormat: @"Thread %ld Crashed:\n", (long) thread.threadNumber];
crashed_thread = thread;
} else {
[xmlString appendFormat: @"Thread %ld:\n", (long) thread.threadNumber];
}
for (NSUInteger frame_idx = 0; frame_idx < [thread.stackFrames count]; frame_idx++) {
PLCrashReportStackFrameInfo *frameInfo = [thread.stackFrames objectAtIndex: frame_idx];
PLCrashReportBinaryImageInfo *imageInfo;
/* Base image address containing instrumention pointer, offset of the IP from that base
* address, and the associated image name */
uint64_t baseAddress = 0x0;
uint64_t pcOffset = 0x0;
NSString *imageName = @"\?\?\?";
imageInfo = [report imageForAddress: frameInfo.instructionPointer];
if (imageInfo != nil) {
imageName = [imageInfo.imageName lastPathComponent];
baseAddress = imageInfo.imageBaseAddress;
pcOffset = frameInfo.instructionPointer - imageInfo.imageBaseAddress;
}
[xmlString appendFormat: @"%-4ld%-36s0x%08" PRIx64 " 0x%" PRIx64 " + %" PRId64 "\n",
(long) frame_idx, [imageName UTF8String], frameInfo.instructionPointer, baseAddress, pcOffset];
}
[xmlString appendString: @"\n"];
}
/* Registers */
if (crashed_thread != nil) {
[xmlString appendFormat: @"Thread %ld crashed with %@ Thread State:\n", (long) crashed_thread.threadNumber, codeType];
int regColumn = 1;
for (PLCrashReportRegisterInfo *reg in crashed_thread.registers) {
NSString *reg_fmt;
/* Use 32-bit or 64-bit fixed width format for the register values */
if (lp64)
reg_fmt = @"%6s:\t0x%016" PRIx64 " ";
else
reg_fmt = @"%6s:\t0x%08" PRIx64 " ";
[xmlString appendFormat: reg_fmt, [reg.registerName UTF8String], reg.registerValue];
if (regColumn % 4 == 0)
[xmlString appendString: @"\n"];
regColumn++;
}
if (regColumn % 3 != 0)
[xmlString appendString: @"\n"];
[xmlString appendString: @"\n"];
}
/* Images */
[xmlString appendFormat:@"Binary Images:\n"];
for (PLCrashReportBinaryImageInfo *imageInfo in report.images) {
NSString *uuid;
/* Fetch the UUID if it exists */
if (imageInfo.hasImageUUID)
uuid = imageInfo.imageUUID;
else
uuid = @"???";
NSString *device = @"\?\?\? (\?\?\?)";
#ifdef _ARM_ARCH_7
device = @"armv7";
#else
device = @"armv6";
#endif
/* base_address - terminating_address file_name identifier (<version>) <uuid> file_path */
[xmlString appendFormat:@"0x%" PRIx64 " - 0x%" PRIx64 " %@ %@ <%@> %@\n",
imageInfo.imageBaseAddress,
imageInfo.imageBaseAddress + imageInfo.imageSize,
[imageInfo.imageName lastPathComponent],
device,
uuid,
imageInfo.imageName];
}
return xmlString;
}
- (void)_checkForFeedbackStatus {
NSMutableURLRequest *request = nil;
request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@api/2/apps/%@/crashes/%@",
self.submissionURL,
[self.appIdentifier stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
_feedbackRequestID
]
]];
[request setCachePolicy: NSURLRequestReloadIgnoringLocalCacheData];
[request setValue:@"Quincy/iOS" forHTTPHeaderField:@"User-Agent"];
[request setValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"];
[request setTimeoutInterval: 15];
[request setHTTPMethod:@"GET"];
_serverResult = CrashReportStatusUnknown;
_statusCode = 200;
// Release when done in the delegate method
_responseData = [[NSMutableData alloc] init];
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(connectionOpened)]) {
[self.delegate connectionOpened];
}
_urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)_postXML:(NSString*)xml toURL:(NSURL*)url {
NSMutableURLRequest *request = nil;
NSString *boundary = @"----FOO";
if (self.appIdentifier) {
request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@api/2/apps/%@/crashes",
self.submissionURL,
[self.appIdentifier stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]
]
]];
} else {
request = [NSMutableURLRequest requestWithURL:url];
}
[request setCachePolicy: NSURLRequestReloadIgnoringLocalCacheData];
[request setValue:@"Quincy/iOS" forHTTPHeaderField:@"User-Agent"];
[request setValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"];
[request setTimeoutInterval: 15];
[request setHTTPMethod:@"POST"];
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
[request setValue:contentType forHTTPHeaderField:@"Content-type"];
NSMutableData *postBody = [NSMutableData data];
[postBody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
if (self.appIdentifier) {
[postBody appendData:[@"Content-Disposition: form-data; name=\"xml\"; filename=\"crash.xml\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithFormat:@"Content-Type: text/xml\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
} else {
[postBody appendData:[@"Content-Disposition: form-data; name=\"xmlstring\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
}
[postBody appendData:[xml dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:postBody];
_serverResult = CrashReportStatusUnknown;
_statusCode = 200;
//Release when done in the delegate method
_responseData = [[NSMutableData alloc] init];
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(connectionOpened)]) {
[self.delegate connectionOpened];
}
_urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (!_urlConnection) {
_sendingInProgress = NO;
}
}
#pragma mark NSURLConnection Delegate
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
_statusCode = [(NSHTTPURLResponse *)response statusCode];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[_responseData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[_responseData release];
_responseData = nil;
[connection autorelease];
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(connectionClosed)]) {
[self.delegate connectionClosed];
}
_sendingInProgress = NO;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
if (_statusCode >= 200 && _statusCode < 400) {
[self _cleanCrashReports];
if (self.appIdentifier) {
// HockeyApp uses PList XML format
NSMutableDictionary *response = [NSPropertyListSerialization propertyListFromData:_responseData
mutabilityOption:NSPropertyListMutableContainersAndLeaves
format:nil
errorDescription:NULL];
_serverResult = (CrashReportStatus)[[response objectForKey:@"status"] intValue];
_feedbackRequestID = [[NSString alloc] initWithString:[response objectForKey:@"id"]];
_feedbackDelayInterval = [[response objectForKey:@"delay"] floatValue];
if (_feedbackDelayInterval > 0)
_feedbackDelayInterval *= 0.01;
} else {
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:_responseData];
// Set self as the delegate of the parser so that it will receive the parser delegate methods callbacks.
[parser setDelegate:self];
// Depending on the XML document you're parsing, you may want to enable these features of NSXMLParser.
[parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
[parser release];
}
if ([self isFeedbackActivated]) {
if (self.appIdentifier) {
// only proceed if the server did not report any problem
if (_serverResult == CrashReportStatusQueued) {
// the report is still in the queue
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(_checkForFeedbackStatus) object:nil];
[self performSelector:@selector(_checkForFeedbackStatus) withObject:nil afterDelay:_feedbackDelayInterval];
} else {
// we do have a status, show it if needed
[self showCrashStatusMessage];
}
} else {
[self showCrashStatusMessage];
}
}
}
[_responseData release];
_responseData = nil;
[connection autorelease];
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(connectionClosed)]) {
[self.delegate connectionClosed];
}
_sendingInProgress = NO;
}
#pragma mark PLCrashReporter
//
// Called to handle a pending crash report.
//
- (void) handleCrashReport {
PLCrashReporter *crashReporter = [PLCrashReporter sharedReporter];
NSError *error = NULL;
// check if the next call ran successfully the last time
if (_analyzerStarted == 0) {
// mark the start of the routine
_analyzerStarted = 1;
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithInt:_analyzerStarted] forKey:kQuincyKitAnalyzerStarted];
[[NSUserDefaults standardUserDefaults] synchronize];
// Try loading the crash report
_crashData = [[NSData alloc] initWithData:[crashReporter loadPendingCrashReportDataAndReturnError: &error]];
NSString *cacheFilename = [NSString stringWithFormat: @"%.0f", [NSDate timeIntervalSinceReferenceDate]];
if (_crashData == nil) {
NSLog(@"Could not load crash report: %@", error);
} else {
[_crashData writeToFile:[_crashesDir stringByAppendingPathComponent: cacheFilename] atomically:YES];
}
}
// Purge the report
// mark the end of the routine
_analyzerStarted = 0;
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithInt:_analyzerStarted] forKey:kQuincyKitAnalyzerStarted];
[[NSUserDefaults standardUserDefaults] synchronize];
[crashReporter purgePendingCrashReport];
return;
}
@end

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>DetectPhoneNumber</key>
<true/>
<key>TopActivityIndicator</key>
<string>gray</string>
<key>EnableLocation</key>
<false/>
<key>EnableAcceleration</key>
<true/>
<key>EnableViewportScale</key>
<false/>
<key>AutoHideSplashScreen</key>
<true/>
<key>ShowSplashScreenSpinner</key>
<true/>
<key>ExternalHosts</key>
<array/>
<key>Plugins</key>
<dict>
<key>HockeyApp</key>
<string>HockeyApp</string>
<key>com.phonegap.accelerometer</key>
<string>PGAccelerometer</string>
<key>com.phonegap.camera</key>
<string>PGCamera</string>
<key>com.phonegap.connection</key>
<string>PGConnection</string>
<key>com.phonegap.contacts</key>
<string>PGContacts</string>
<key>com.phonegap.debugconsole</key>
<string>PGDebugConsole</string>
<key>com.phonegap.file</key>
<string>PGFile</string>
<key>com.phonegap.filetransfer</key>
<string>PGFileTransfer</string>
<key>com.phonegap.geolocation</key>
<string>PGLocation</string>
<key>com.phonegap.notification</key>
<string>PGNotification</string>
<key>com.phonegap.media</key>
<string>PGSound</string>
<key>com.phonegap.mediacapture</key>
<string>PGCapture</string>
<key>com.phonegap.splashscreen</key>
<string>PGSplashScreen</string>
</dict>
</dict>
</plist>

View File

@@ -0,0 +1 @@
Put the .h and .m files of your plugin here. The .js files of your plugin belong in the www folder.

Binary file not shown.

After

Width:  |  Height:  |  Size: 955 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 971 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 969 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Some files were not shown because too many files have changed in this diff Show More