Updated for XCode 4.5
Cleanup and removal of redundant shader compiling and validation code --HG-- extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40101
This commit is contained in:
@@ -948,7 +948,7 @@
|
|||||||
GCC_VERSION = com.apple.compilers.llvmgcc42;
|
GCC_VERSION = com.apple.compilers.llvmgcc42;
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 4.3;
|
IPHONEOS_DEPLOYMENT_TARGET = 5.0;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
@@ -963,7 +963,7 @@
|
|||||||
GCC_VERSION = com.apple.compilers.llvmgcc42;
|
GCC_VERSION = com.apple.compilers.llvmgcc42;
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 4.3;
|
IPHONEOS_DEPLOYMENT_TARGET = 5.0;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
|
|||||||
@@ -448,7 +448,6 @@ void KRCamera::createBuffers() {
|
|||||||
GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, lightAccumulationTexture, 0));
|
GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, lightAccumulationTexture, 0));
|
||||||
|
|
||||||
allocateShadowBuffers();
|
allocateShadowBuffers();
|
||||||
loadShaders();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KRCamera::allocateShadowBuffers() {
|
void KRCamera::allocateShadowBuffers() {
|
||||||
@@ -544,26 +543,19 @@ void KRCamera::renderShadowBuffer(KRScene &scene, int iShadow)
|
|||||||
GLDEBUG(glDisable(GL_BLEND));
|
GLDEBUG(glDisable(GL_BLEND));
|
||||||
|
|
||||||
// Use shader program
|
// Use shader program
|
||||||
GLDEBUG(glUseProgram(m_shadowShaderProgram));
|
KRShader *shadowShader = m_pContext->getShaderManager()->getShader("ShadowShader", this, false, false, false, 0, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||||
|
KRMat4 matIdentity; // Value not used by postshader
|
||||||
|
KRVector3 vec4Temp; // Value not used by postshader
|
||||||
|
shadowShader->bind(this, matIdentity, matIdentity, m_position, vec4Temp, NULL, NULL, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||||
|
|
||||||
// Sets the diffuseTexture variable to the first texture unit
|
// Sets the diffuseTexture variable to the first texture unit
|
||||||
/*
|
/*
|
||||||
glUniform1i(glGetUniformLocation(m_shadowShaderProgram, "diffuseTexture"), 0);
|
glUniform1i(glGetUniformLocation(m_shadowShaderProgram, "diffuseTexture"), 0);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Validate program before drawing. This is a good check, but only really necessary in a debug build.
|
|
||||||
// DEBUG macro must be defined in your debug configurations if that's not already the case.
|
|
||||||
#if defined(DEBUG)
|
|
||||||
if (!ValidateProgram(m_shadowShaderProgram)) {
|
|
||||||
fprintf(stderr, "Failed to validate program: %d", m_shadowShaderProgram);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Bind our modelmatrix variable to be a uniform called mvpmatrix in our shaderprogram
|
// Bind our modelmatrix variable to be a uniform called mvpmatrix in our shaderprogram
|
||||||
GLDEBUG(glUniformMatrix4fv(m_shadowUniforms[KRENGINE_UNIFORM_SHADOWMVP1], 1, GL_FALSE, shadowmvpmatrix[iShadow].getPointer()));
|
GLDEBUG(glUniformMatrix4fv(shadowShader->m_uniforms[KRShader::KRENGINE_UNIFORM_SHADOWMVP1], 1, GL_FALSE, shadowmvpmatrix[iShadow].getPointer()));
|
||||||
|
|
||||||
|
|
||||||
// Calculate the bounding volume of the light map
|
// Calculate the bounding volume of the light map
|
||||||
@@ -592,28 +584,6 @@ void KRCamera::renderShadowBuffer(KRScene &scene, int iShadow)
|
|||||||
GLDEBUG(glViewport(0, 0, backingWidth, backingHeight));
|
GLDEBUG(glViewport(0, 0, backingWidth, backingHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool KRCamera::ValidateProgram(GLuint prog)
|
|
||||||
{
|
|
||||||
GLint logLength, status;
|
|
||||||
|
|
||||||
GLDEBUG(glValidateProgram(prog));
|
|
||||||
GLDEBUG(glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength));
|
|
||||||
if (logLength > 0)
|
|
||||||
{
|
|
||||||
GLchar *log = (GLchar *)malloc(logLength);
|
|
||||||
GLDEBUG(glGetProgramInfoLog(prog, logLength, &logLength, log));
|
|
||||||
fprintf(stderr, "Program validate log:\n%s", log);
|
|
||||||
free(log);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLDEBUG(glGetProgramiv(prog, GL_VALIDATE_STATUS, &status));
|
|
||||||
if (status == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void KRCamera::renderPost()
|
void KRCamera::renderPost()
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -760,150 +730,6 @@ void KRCamera::invalidateShadowBuffers() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool KRCamera::LoadShader(KRContext &context, const std::string &name, GLuint *programPointer, const std::string &options)
|
|
||||||
{
|
|
||||||
GLuint vertexShader, fragShader;
|
|
||||||
|
|
||||||
// Create shader program.
|
|
||||||
GLDEBUG(*programPointer = glCreateProgram());
|
|
||||||
|
|
||||||
// Create and compile vertex shader.
|
|
||||||
|
|
||||||
if(!CompileShader(&vertexShader, GL_VERTEX_SHADER, context.getShaderManager()->getVertShaderSource(name), options)) {
|
|
||||||
fprintf(stderr, "Failed to compile vertex shader");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create and compile fragment shader.
|
|
||||||
if(!CompileShader(&fragShader, GL_FRAGMENT_SHADER, context.getShaderManager()->getFragShaderSource(name), options)) {
|
|
||||||
fprintf(stderr, "Failed to compile fragment shader");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attach vertex shader to program.
|
|
||||||
GLDEBUG(glAttachShader(*programPointer, vertexShader));
|
|
||||||
|
|
||||||
// Attach fragment shader to program.
|
|
||||||
GLDEBUG(glAttachShader(*programPointer, fragShader));
|
|
||||||
|
|
||||||
// Bind attribute locations.
|
|
||||||
// This needs to be done prior to linking.
|
|
||||||
GLDEBUG(glBindAttribLocation(*programPointer, KRShader::KRENGINE_ATTRIB_TEXUVB, "vertex_lightmap_uv"));
|
|
||||||
GLDEBUG(glBindAttribLocation(*programPointer, KRShader::KRENGINE_ATTRIB_VERTEX, "vertex_position"));
|
|
||||||
GLDEBUG(glBindAttribLocation(*programPointer, KRShader::KRENGINE_ATTRIB_NORMAL, "vertex_normal"));
|
|
||||||
GLDEBUG(glBindAttribLocation(*programPointer, KRShader::KRENGINE_ATTRIB_TANGENT, "vertex_tangent"));
|
|
||||||
GLDEBUG(glBindAttribLocation(*programPointer, KRShader::KRENGINE_ATTRIB_TEXUVA, "vertex_uv"));
|
|
||||||
|
|
||||||
// Link program.
|
|
||||||
if(!LinkProgram(*programPointer)) {
|
|
||||||
fprintf(stderr, "Failed to link program: %d", *programPointer);
|
|
||||||
|
|
||||||
if (vertexShader) {
|
|
||||||
GLDEBUG(glDeleteShader(vertexShader));
|
|
||||||
vertexShader = 0;
|
|
||||||
}
|
|
||||||
if (fragShader) {
|
|
||||||
GLDEBUG(glDeleteShader(fragShader));
|
|
||||||
fragShader = 0;
|
|
||||||
}
|
|
||||||
if (*programPointer) {
|
|
||||||
GLDEBUG(glDeleteProgram(*programPointer));
|
|
||||||
*programPointer = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Release vertex and fragment shaders.
|
|
||||||
if (vertexShader)
|
|
||||||
{
|
|
||||||
GLDEBUG(glDeleteShader(vertexShader));
|
|
||||||
}
|
|
||||||
if (fragShader)
|
|
||||||
{
|
|
||||||
GLDEBUG(glDeleteShader(fragShader));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool KRCamera::CompileShader(GLuint *shader, GLenum type, const std::string &shader_source, const std::string &options)
|
|
||||||
{
|
|
||||||
GLint status;
|
|
||||||
const GLchar *source[2];
|
|
||||||
|
|
||||||
source[0] = (GLchar *)shader_source.c_str();
|
|
||||||
if (!source[0])
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Failed to load vertex shader");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(options.length()) {
|
|
||||||
source[1] = source[0];
|
|
||||||
source[0] = options.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GLDEBUG(*shader = glCreateShader(type));
|
|
||||||
GLDEBUG(glShaderSource(*shader, options.length() ? 2 : 1, source, NULL));
|
|
||||||
GLDEBUG(glCompileShader(*shader));
|
|
||||||
|
|
||||||
#if defined(DEBUG)
|
|
||||||
GLint logLength;
|
|
||||||
GLDEBUG(glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength));
|
|
||||||
if (logLength > 0)
|
|
||||||
{
|
|
||||||
GLchar *log = (GLchar *)malloc(logLength);
|
|
||||||
GLDEBUG(glGetShaderInfoLog(*shader, logLength, &logLength, log));
|
|
||||||
fprintf(stderr, "Shader compile log:\n%s", log);
|
|
||||||
free(log);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
GLDEBUG(glGetShaderiv(*shader, GL_COMPILE_STATUS, &status));
|
|
||||||
if (status == 0) {
|
|
||||||
GLDEBUG(glDeleteShader(*shader));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool KRCamera::LinkProgram(GLuint prog)
|
|
||||||
{
|
|
||||||
GLint status;
|
|
||||||
|
|
||||||
GLDEBUG(glLinkProgram(prog));
|
|
||||||
|
|
||||||
#if defined(DEBUG)
|
|
||||||
GLint logLength;
|
|
||||||
GLDEBUG(glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength));
|
|
||||||
if (logLength > 0)
|
|
||||||
{
|
|
||||||
GLchar *log = (GLchar *)malloc(logLength);
|
|
||||||
GLDEBUG(glGetProgramInfoLog(prog, logLength, &logLength, log));
|
|
||||||
fprintf(stderr, "Program link log:\n%s", log);
|
|
||||||
free(log);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
GLDEBUG(glGetProgramiv(prog, GL_LINK_STATUS, &status));
|
|
||||||
if (status == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void KRCamera::loadShaders()
|
|
||||||
{
|
|
||||||
LoadShader(*m_pContext, "ShadowShader", &m_shadowShaderProgram, "");
|
|
||||||
|
|
||||||
m_shadowUniforms[KRENGINE_UNIFORM_SHADOWMVP1] = glGetUniformLocation(m_shadowShaderProgram, "shadow_mvp1");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void KRCamera::notify_sceneGraphCreate(KRNode *pNode)
|
void KRCamera::notify_sceneGraphCreate(KRNode *pNode)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "KRCamera - notify_sceneGraphCreate");
|
fprintf(stderr, "KRCamera - notify_sceneGraphCreate");
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
#import "KRVector2.h"
|
#import "KRVector2.h"
|
||||||
#import "KRNotified.h"
|
#import "KRNotified.h"
|
||||||
#import "KRAABB.h"
|
#import "KRAABB.h"
|
||||||
|
#import "KRShader.h"
|
||||||
|
|
||||||
|
|
||||||
#define KRENGINE_MAX_SHADOW_BUFFERS 3
|
#define KRENGINE_MAX_SHADOW_BUFFERS 3
|
||||||
@@ -127,51 +128,15 @@ private:
|
|||||||
bool shadowValid[KRENGINE_MAX_SHADOW_BUFFERS];
|
bool shadowValid[KRENGINE_MAX_SHADOW_BUFFERS];
|
||||||
KRMat4 shadowmvpmatrix[KRENGINE_MAX_SHADOW_BUFFERS]; /* MVP Matrix for view from light source */
|
KRMat4 shadowmvpmatrix[KRENGINE_MAX_SHADOW_BUFFERS]; /* MVP Matrix for view from light source */
|
||||||
|
|
||||||
|
|
||||||
// uniform index
|
|
||||||
enum {
|
|
||||||
KRENGINE_UNIFORM_MATERIAL_AMBIENT,
|
|
||||||
KRENGINE_UNIFORM_MATERIAL_DIFFUSE,
|
|
||||||
KRENGINE_UNIFORM_MATERIAL_SPECULAR,
|
|
||||||
KRENGINE_UNIFORM_LIGHT_POSITION,
|
|
||||||
KRENGINE_UNIFORM_LIGHT_POSITION_VIEW_SPACE,
|
|
||||||
KRENGINE_UNIFORM_LIGHT_DIRECTION,
|
|
||||||
KRENGINE_UNIFORM_LIGHT_DIRECTION_VIEW_SPACE,
|
|
||||||
KRENGINE_UNIFORM_LIGHT_COLOR,
|
|
||||||
KRENGINE_UNIFORM_LIGHT_DECAY_START,
|
|
||||||
KRENGINE_UNIFORM_LIGHT_CUTOFF,
|
|
||||||
KRENGINE_UNIFORM_LIGHT_INTENSITY,
|
|
||||||
KRENGINE_UNIFORM_FLARE_SIZE,
|
|
||||||
KRENGINE_UNIFORM_MVP,
|
|
||||||
KRENGINE_UNIFORM_INVP,
|
|
||||||
KRENGINE_UNIFORM_MN2V,
|
|
||||||
KRENGINE_UNIFORM_M2V,
|
|
||||||
KRENGINE_UNIFORM_V2M,
|
|
||||||
KRENGINE_UNIFORM_SHADOWMVP1,
|
|
||||||
KRENGINE_UNIFORM_SHADOWMVP2,
|
|
||||||
KRENGINE_UNIFORM_SHADOWMVP3,
|
|
||||||
|
|
||||||
KRENGINE_UNIFORM_CAMERAPOS,
|
|
||||||
KRENGINE_UNIFORM_VIEWPORT,
|
|
||||||
KRENGINE_NUM_UNIFORMS
|
|
||||||
};
|
|
||||||
GLint m_shadowUniforms[KRENGINE_NUM_UNIFORMS];
|
|
||||||
|
|
||||||
GLuint m_shadowShaderProgram;
|
|
||||||
|
|
||||||
void renderPost();
|
void renderPost();
|
||||||
|
|
||||||
void destroyBuffers();
|
void destroyBuffers();
|
||||||
|
|
||||||
void renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightDirection, KRVector3 &cameraPosition);
|
void renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightDirection, KRVector3 &cameraPosition);
|
||||||
|
|
||||||
void loadShaders();
|
|
||||||
|
|
||||||
// Code using these shader functions will later be refactored to integrate with KRShaderManager
|
|
||||||
static bool ValidateProgram(GLuint prog);
|
|
||||||
static bool LoadShader(KRContext &context, const std::string &name, GLuint *programPointer, const std::string &options);
|
|
||||||
static bool CompileShader(GLuint *shader, GLenum type, const std::string &shader_source, const std::string &options);
|
|
||||||
static bool LinkProgram(GLuint prog);
|
|
||||||
|
|
||||||
|
|
||||||
class KRInstanceDistance {
|
class KRInstanceDistance {
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ void KRContext::loadResource(const std::string &file_name, KRDataBlock *data) {
|
|||||||
std::string name = KRResource::GetFileBase(file_name);
|
std::string name = KRResource::GetFileBase(file_name);
|
||||||
std::string extension = KRResource::GetFileExtension(file_name);
|
std::string extension = KRResource::GetFileExtension(file_name);
|
||||||
|
|
||||||
fprintf(stderr, "KRContext::loadResource - Loading: %s\n", file_name.c_str());
|
//fprintf(stderr, "KRContext::loadResource - Loading: %s\n", file_name.c_str());
|
||||||
|
|
||||||
if(extension.compare("krbundle") == 0) {
|
if(extension.compare("krbundle") == 0) {
|
||||||
m_pBundleManager->loadBundle(name.c_str(), data);
|
m_pBundleManager->loadBundle(name.c_str(), data);
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ vector<KRMesh::Submesh *> KRMesh::getSubmeshes() {
|
|||||||
return m_submeshes;
|
return m_submeshes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KRMesh::renderSubmesh(int iSubmesh, int &iPrevBuffer) {
|
void KRMesh::renderSubmesh(int iSubmesh) {
|
||||||
VertexData *pVertexData = getVertexData();
|
VertexData *pVertexData = getVertexData();
|
||||||
|
|
||||||
pack_header *pHeader = (pack_header *)m_pData->getStart();
|
pack_header *pHeader = (pack_header *)m_pData->getStart();
|
||||||
@@ -122,15 +122,14 @@ void KRMesh::renderSubmesh(int iSubmesh, int &iPrevBuffer) {
|
|||||||
int cVertexes = pSubmesh->vertex_count;
|
int cVertexes = pSubmesh->vertex_count;
|
||||||
while(cVertexes > 0) {
|
while(cVertexes > 0) {
|
||||||
GLsizei cBufferVertexes = iBuffer < cBuffers - 1 ? MAX_VBO_SIZE : pHeader->vertex_count % MAX_VBO_SIZE;
|
GLsizei cBufferVertexes = iBuffer < cBuffers - 1 ? MAX_VBO_SIZE : pHeader->vertex_count % MAX_VBO_SIZE;
|
||||||
if(iPrevBuffer != iBuffer) {
|
|
||||||
assert(pVertexData + iBuffer * MAX_VBO_SIZE >= m_pData->getStart());
|
assert(pVertexData + iBuffer * MAX_VBO_SIZE >= m_pData->getStart());
|
||||||
int vertex_size = sizeof(VertexData) ;
|
int vertex_size = sizeof(VertexData) ;
|
||||||
void *vbo_end = (unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE + vertex_size * cBufferVertexes;
|
void *vbo_end = (unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE + vertex_size * cBufferVertexes;
|
||||||
void *buffer_end = m_pData->getEnd();
|
void *buffer_end = m_pData->getEnd();
|
||||||
assert(vbo_end <= buffer_end);
|
assert(vbo_end <= buffer_end);
|
||||||
m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE, sizeof(VertexData) * cBufferVertexes, true, true, true, true, true);
|
m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE, vertex_size * cBufferVertexes, true, true, true, true, true);
|
||||||
}
|
|
||||||
iPrevBuffer = iBuffer;
|
|
||||||
|
|
||||||
if(iVertex + cVertexes >= MAX_VBO_SIZE) {
|
if(iVertex + cVertexes >= MAX_VBO_SIZE) {
|
||||||
assert(iVertex + (MAX_VBO_SIZE - iVertex) <= cBufferVertexes);
|
assert(iVertex + (MAX_VBO_SIZE - iVertex) <= cBufferVertexes);
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public:
|
|||||||
void loadPack(KRDataBlock *data);
|
void loadPack(KRDataBlock *data);
|
||||||
|
|
||||||
|
|
||||||
void renderSubmesh(int iSubmesh, int &iPrevBuffer);
|
void renderSubmesh(int iSubmesh);
|
||||||
|
|
||||||
GLfloat getMaxDimension();
|
GLfloat getMaxDimension();
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,6 @@ void KRModel::render(KRCamera *pCamera, KRContext *pContext, KRMat4 &matModelToV
|
|||||||
}
|
}
|
||||||
|
|
||||||
KRMaterial *pPrevBoundMaterial = NULL;
|
KRMaterial *pPrevBoundMaterial = NULL;
|
||||||
int iPrevBuffer = -1;
|
|
||||||
char szPrevShaderKey[128];
|
char szPrevShaderKey[128];
|
||||||
szPrevShaderKey[0] = '\0';
|
szPrevShaderKey[0] = '\0';
|
||||||
int cSubmeshes = m_pMesh->getSubmeshes().size();
|
int cSubmeshes = m_pMesh->getSubmeshes().size();
|
||||||
@@ -105,7 +104,7 @@ void KRModel::render(KRCamera *pCamera, KRContext *pContext, KRMat4 &matModelToV
|
|||||||
|
|
||||||
if(!pMaterial->isTransparent()) {
|
if(!pMaterial->isTransparent()) {
|
||||||
// Exclude transparent and semi-transparent meshes from shadow maps
|
// Exclude transparent and semi-transparent meshes from shadow maps
|
||||||
m_pMesh->renderSubmesh(iSubmesh, iPrevBuffer);
|
m_pMesh->renderSubmesh(iSubmesh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,19 +122,19 @@ void KRModel::render(KRCamera *pCamera, KRContext *pContext, KRMat4 &matModelToV
|
|||||||
switch(pMaterial->getAlphaMode()) {
|
switch(pMaterial->getAlphaMode()) {
|
||||||
case KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE: // Non-transparent materials
|
case KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE: // Non-transparent materials
|
||||||
case KRMaterial::KRMATERIAL_ALPHA_MODE_TEST: // Alpha in diffuse texture is interpreted as punch-through when < 0.5
|
case KRMaterial::KRMATERIAL_ALPHA_MODE_TEST: // Alpha in diffuse texture is interpreted as punch-through when < 0.5
|
||||||
m_pMesh->renderSubmesh(iSubmesh, iPrevBuffer);
|
m_pMesh->renderSubmesh(iSubmesh);
|
||||||
break;
|
break;
|
||||||
case KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDONESIDE: // Blended alpha with backface culling
|
case KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDONESIDE: // Blended alpha with backface culling
|
||||||
m_pMesh->renderSubmesh(iSubmesh, iPrevBuffer);
|
m_pMesh->renderSubmesh(iSubmesh);
|
||||||
break;
|
break;
|
||||||
case KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE: // Blended alpha rendered in two passes. First pass renders backfaces; second pass renders frontfaces.
|
case KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE: // Blended alpha rendered in two passes. First pass renders backfaces; second pass renders frontfaces.
|
||||||
// Render back faces first
|
// Render back faces first
|
||||||
GLDEBUG(glCullFace(GL_BACK));
|
GLDEBUG(glCullFace(GL_BACK));
|
||||||
m_pMesh->renderSubmesh(iSubmesh, iPrevBuffer);
|
m_pMesh->renderSubmesh(iSubmesh);
|
||||||
|
|
||||||
// Render front faces second
|
// Render front faces second
|
||||||
GLDEBUG(glCullFace(GL_BACK));
|
GLDEBUG(glCullFace(GL_BACK));
|
||||||
m_pMesh->renderSubmesh(iSubmesh, iPrevBuffer);
|
m_pMesh->renderSubmesh(iSubmesh);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ KRShader *KRShaderManager::getShader(std::string shader_name, KRCamera *pCamera,
|
|||||||
|
|
||||||
stream << "\n";
|
stream << "\n";
|
||||||
std::string options = stream.str();
|
std::string options = stream.str();
|
||||||
fprintf(stderr, "Shader Options:\n%s\n\n", options.c_str());
|
//fprintf(stderr, "Shader Options:\n%s\n\n", options.c_str());
|
||||||
|
|
||||||
pShader = new KRShader(szKey, options, m_vertShaderSource[shader_name], m_fragShaderSource[shader_name]);
|
pShader = new KRShader(szKey, options, m_vertShaderSource[shader_name], m_fragShaderSource[shader_name]);
|
||||||
|
|
||||||
|
|||||||
@@ -19,14 +19,9 @@
|
|||||||
288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; };
|
288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; };
|
||||||
28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; };
|
28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; };
|
||||||
28D7ACF80DDB3853001CB0EB /* KRObjViewViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 28D7ACF70DDB3853001CB0EB /* KRObjViewViewController.mm */; };
|
28D7ACF80DDB3853001CB0EB /* KRObjViewViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 28D7ACF70DDB3853001CB0EB /* KRObjViewViewController.mm */; };
|
||||||
E40611D714E4E98B0065996A /* README.txt in Resources */ = {isa = PBXBuildFile; fileRef = E40611D314E4E98B0065996A /* README.txt */; };
|
|
||||||
E40611D814E4E98B0065996A /* release_notes.txt in Resources */ = {isa = PBXBuildFile; fileRef = E40611D414E4E98B0065996A /* release_notes.txt */; };
|
|
||||||
E430D08615F88A9F0010558D /* occlusion_test.fsh in Sources */ = {isa = PBXBuildFile; fileRef = E430D08515F88A9F0010558D /* occlusion_test.fsh */; };
|
|
||||||
E430D08B15F88B950010558D /* occlusion_test.vsh in Sources */ = {isa = PBXBuildFile; fileRef = E430D08A15F88B950010558D /* occlusion_test.vsh */; };
|
|
||||||
E430D08C15F88BC50010558D /* occlusion_test.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E430D08A15F88B950010558D /* occlusion_test.vsh */; };
|
E430D08C15F88BC50010558D /* occlusion_test.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E430D08A15F88B950010558D /* occlusion_test.vsh */; };
|
||||||
E430D08D15F88BC70010558D /* occlusion_test.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E430D08515F88A9F0010558D /* occlusion_test.fsh */; };
|
E430D08D15F88BC70010558D /* occlusion_test.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E430D08515F88A9F0010558D /* occlusion_test.fsh */; };
|
||||||
E43A7A6E13CA2BA2000A565E /* libKREngine.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E43A7A6D13CA2BA2000A565E /* libKREngine.a */; };
|
E43A7A6E13CA2BA2000A565E /* libKREngine.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E43A7A6D13CA2BA2000A565E /* libKREngine.a */; };
|
||||||
E46DBE831512B7C300D59F86 /* libTestFlight.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E40611D214E4E98B0065996A /* libTestFlight.a */; };
|
|
||||||
E46FED2D13C9A49F009F5814 /* ShadowShader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E46FED2113C9A488009F5814 /* ShadowShader.vsh */; };
|
E46FED2D13C9A49F009F5814 /* ShadowShader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E46FED2113C9A488009F5814 /* ShadowShader.vsh */; };
|
||||||
E46FED2E13C9A49F009F5814 /* ShadowShader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E46FED2213C9A488009F5814 /* ShadowShader.fsh */; };
|
E46FED2E13C9A49F009F5814 /* ShadowShader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E46FED2213C9A488009F5814 /* ShadowShader.fsh */; };
|
||||||
E46FED2F13C9A49F009F5814 /* PostShader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E46FED2313C9A488009F5814 /* PostShader.fsh */; };
|
E46FED2F13C9A49F009F5814 /* PostShader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E46FED2313C9A488009F5814 /* PostShader.fsh */; };
|
||||||
@@ -36,14 +31,15 @@
|
|||||||
E4769DF3158A7915004B83AC /* flare.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4769DF1158A7915004B83AC /* flare.fsh */; };
|
E4769DF3158A7915004B83AC /* flare.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4769DF1158A7915004B83AC /* flare.fsh */; };
|
||||||
E4769DF4158A7915004B83AC /* flare.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E4769DF2158A7915004B83AC /* flare.vsh */; };
|
E4769DF4158A7915004B83AC /* flare.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E4769DF2158A7915004B83AC /* flare.vsh */; };
|
||||||
E48278B415F037B9001C9431 /* visualize_overlay.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E48278B215F037B9001C9431 /* visualize_overlay.vsh */; };
|
E48278B415F037B9001C9431 /* visualize_overlay.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E48278B215F037B9001C9431 /* visualize_overlay.vsh */; };
|
||||||
E48839A415F92C6900BD66D5 /* visualize_overlay.fsh in Sources */ = {isa = PBXBuildFile; fileRef = E48839A315F92C6900BD66D5 /* visualize_overlay.fsh */; };
|
|
||||||
E48839A515F92C8D00BD66D5 /* visualize_overlay.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E48839A315F92C6900BD66D5 /* visualize_overlay.fsh */; };
|
E48839A515F92C8D00BD66D5 /* visualize_overlay.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E48839A315F92C6900BD66D5 /* visualize_overlay.fsh */; };
|
||||||
|
E48BB5F9160AEF16008477A6 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = E48BB5F7160AEF16008477A6 /* README.md */; };
|
||||||
|
E48BB5FA160AEF16008477A6 /* release_notes.md in Resources */ = {isa = PBXBuildFile; fileRef = E48BB5F8160AEF16008477A6 /* release_notes.md */; };
|
||||||
|
E48BB5FC160AF61C008477A6 /* libTestFlight.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E40611D214E4E98B0065996A /* libTestFlight.a */; };
|
||||||
|
E48BB5FE160AF8B9008477A6 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E48BB5FD160AF8B9008477A6 /* libz.dylib */; };
|
||||||
E49EB29C13806C5D00A4E727 /* MainWindow-iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = E49EB29B13806C5D00A4E727 /* MainWindow-iPad.xib */; };
|
E49EB29C13806C5D00A4E727 /* MainWindow-iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = E49EB29B13806C5D00A4E727 /* MainWindow-iPad.xib */; };
|
||||||
E4A9DEC715412923009DF363 /* light_point.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4A9DEC2154128F0009DF363 /* light_point.fsh */; };
|
E4A9DEC715412923009DF363 /* light_point.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4A9DEC2154128F0009DF363 /* light_point.fsh */; };
|
||||||
E4A9DEC815412923009DF363 /* light_point.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E4A9DEC515412906009DF363 /* light_point.vsh */; };
|
E4A9DEC815412923009DF363 /* light_point.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E4A9DEC515412906009DF363 /* light_point.vsh */; };
|
||||||
E4CE184A15FEEE8500F80870 /* font.pvr in Resources */ = {isa = PBXBuildFile; fileRef = E4CE184915FEEE8500F80870 /* font.pvr */; };
|
E4CE184A15FEEE8500F80870 /* font.pvr in Resources */ = {isa = PBXBuildFile; fileRef = E4CE184915FEEE8500F80870 /* font.pvr */; };
|
||||||
E4CE185215FF12A700F80870 /* light_point_inside.fsh in Sources */ = {isa = PBXBuildFile; fileRef = E4CE185015FF12A700F80870 /* light_point_inside.fsh */; };
|
|
||||||
E4CE185315FF12A700F80870 /* light_point_inside.vsh in Sources */ = {isa = PBXBuildFile; fileRef = E4CE185115FF12A700F80870 /* light_point_inside.vsh */; };
|
|
||||||
E4CE185415FF12B700F80870 /* light_point_inside.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4CE185015FF12A700F80870 /* light_point_inside.fsh */; };
|
E4CE185415FF12B700F80870 /* light_point_inside.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4CE185015FF12A700F80870 /* light_point_inside.fsh */; };
|
||||||
E4CE185515FF12B700F80870 /* light_point_inside.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E4CE185115FF12A700F80870 /* light_point_inside.vsh */; };
|
E4CE185515FF12B700F80870 /* light_point_inside.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E4CE185115FF12A700F80870 /* light_point_inside.vsh */; };
|
||||||
E4FF48C51538FBF8002053FC /* light_directional.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4FF48C01538FBF0002053FC /* light_directional.fsh */; };
|
E4FF48C51538FBF8002053FC /* light_directional.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4FF48C01538FBF0002053FC /* light_directional.fsh */; };
|
||||||
@@ -70,8 +66,6 @@
|
|||||||
32CA4F630368D1EE00C91783 /* KRObjView_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRObjView_Prefix.pch; sourceTree = "<group>"; };
|
32CA4F630368D1EE00C91783 /* KRObjView_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRObjView_Prefix.pch; sourceTree = "<group>"; };
|
||||||
8D1107310486CEB800E47090 /* KRObjView-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "KRObjView-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; };
|
8D1107310486CEB800E47090 /* KRObjView-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "KRObjView-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; };
|
||||||
E40611D214E4E98B0065996A /* libTestFlight.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libTestFlight.a; sourceTree = "<group>"; };
|
E40611D214E4E98B0065996A /* libTestFlight.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libTestFlight.a; sourceTree = "<group>"; };
|
||||||
E40611D314E4E98B0065996A /* README.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.txt; sourceTree = "<group>"; };
|
|
||||||
E40611D414E4E98B0065996A /* release_notes.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = release_notes.txt; sourceTree = "<group>"; };
|
|
||||||
E40611D514E4E98B0065996A /* TestFlight.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = TestFlight.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
E40611D514E4E98B0065996A /* TestFlight.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = TestFlight.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||||
E430D08515F88A9F0010558D /* occlusion_test.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = occlusion_test.fsh; path = ../KREngine/KREngine/Shaders/occlusion_test.fsh; sourceTree = "<group>"; };
|
E430D08515F88A9F0010558D /* occlusion_test.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = occlusion_test.fsh; path = ../KREngine/KREngine/Shaders/occlusion_test.fsh; sourceTree = "<group>"; };
|
||||||
E430D08A15F88B950010558D /* occlusion_test.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = occlusion_test.vsh; path = ../KREngine/KREngine/Shaders/occlusion_test.vsh; sourceTree = "<group>"; };
|
E430D08A15F88B950010558D /* occlusion_test.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = occlusion_test.vsh; path = ../KREngine/KREngine/Shaders/occlusion_test.vsh; sourceTree = "<group>"; };
|
||||||
@@ -86,6 +80,9 @@
|
|||||||
E4769DF2158A7915004B83AC /* flare.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = flare.vsh; path = ../KREngine/KREngine/Shaders/flare.vsh; sourceTree = "<group>"; };
|
E4769DF2158A7915004B83AC /* flare.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = flare.vsh; path = ../KREngine/KREngine/Shaders/flare.vsh; sourceTree = "<group>"; };
|
||||||
E48278B215F037B9001C9431 /* visualize_overlay.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = visualize_overlay.vsh; path = ../KREngine/KREngine/Shaders/visualize_overlay.vsh; sourceTree = "<group>"; };
|
E48278B215F037B9001C9431 /* visualize_overlay.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = visualize_overlay.vsh; path = ../KREngine/KREngine/Shaders/visualize_overlay.vsh; sourceTree = "<group>"; };
|
||||||
E48839A315F92C6900BD66D5 /* visualize_overlay.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = visualize_overlay.fsh; path = ../KREngine/KREngine/Shaders/visualize_overlay.fsh; sourceTree = "<group>"; };
|
E48839A315F92C6900BD66D5 /* visualize_overlay.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = visualize_overlay.fsh; path = ../KREngine/KREngine/Shaders/visualize_overlay.fsh; sourceTree = "<group>"; };
|
||||||
|
E48BB5F7160AEF16008477A6 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = "<group>"; };
|
||||||
|
E48BB5F8160AEF16008477A6 /* release_notes.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = release_notes.md; sourceTree = "<group>"; };
|
||||||
|
E48BB5FD160AF8B9008477A6 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
|
||||||
E49EB29B13806C5D00A4E727 /* MainWindow-iPad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = "MainWindow-iPad.xib"; path = "iPad/MainWindow-iPad.xib"; sourceTree = "<group>"; };
|
E49EB29B13806C5D00A4E727 /* MainWindow-iPad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = "MainWindow-iPad.xib"; path = "iPad/MainWindow-iPad.xib"; sourceTree = "<group>"; };
|
||||||
E4A9DEC2154128F0009DF363 /* light_point.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = light_point.fsh; path = ../KREngine/KREngine/Shaders/light_point.fsh; sourceTree = "<group>"; };
|
E4A9DEC2154128F0009DF363 /* light_point.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = light_point.fsh; path = ../KREngine/KREngine/Shaders/light_point.fsh; sourceTree = "<group>"; };
|
||||||
E4A9DEC515412906009DF363 /* light_point.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = light_point.vsh; path = ../KREngine/KREngine/Shaders/light_point.vsh; sourceTree = "<group>"; };
|
E4A9DEC515412906009DF363 /* light_point.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = light_point.vsh; path = ../KREngine/KREngine/Shaders/light_point.vsh; sourceTree = "<group>"; };
|
||||||
@@ -101,8 +98,9 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
E48BB5FE160AF8B9008477A6 /* libz.dylib in Frameworks */,
|
||||||
|
E48BB5FC160AF61C008477A6 /* libTestFlight.a in Frameworks */,
|
||||||
E43A7A6E13CA2BA2000A565E /* libKREngine.a in Frameworks */,
|
E43A7A6E13CA2BA2000A565E /* libKREngine.a in Frameworks */,
|
||||||
E46DBE831512B7C300D59F86 /* libTestFlight.a in Frameworks */,
|
|
||||||
1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */,
|
1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */,
|
||||||
1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */,
|
1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */,
|
||||||
288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */,
|
288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */,
|
||||||
@@ -140,6 +138,7 @@
|
|||||||
29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
|
29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
E48BB5FD160AF8B9008477A6 /* libz.dylib */,
|
||||||
E4BBBBA31512A57800F43B5B /* libraries */,
|
E4BBBBA31512A57800F43B5B /* libraries */,
|
||||||
E40611D114E4E98B0065996A /* testflight */,
|
E40611D114E4E98B0065996A /* testflight */,
|
||||||
080E96DDFE201D6D7F000001 /* Classes */,
|
080E96DDFE201D6D7F000001 /* Classes */,
|
||||||
@@ -197,9 +196,9 @@
|
|||||||
E40611D114E4E98B0065996A /* testflight */ = {
|
E40611D114E4E98B0065996A /* testflight */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
E48BB5F7160AEF16008477A6 /* README.md */,
|
||||||
|
E48BB5F8160AEF16008477A6 /* release_notes.md */,
|
||||||
E40611D214E4E98B0065996A /* libTestFlight.a */,
|
E40611D214E4E98B0065996A /* libTestFlight.a */,
|
||||||
E40611D314E4E98B0065996A /* README.txt */,
|
|
||||||
E40611D414E4E98B0065996A /* release_notes.txt */,
|
|
||||||
E40611D514E4E98B0065996A /* TestFlight.h */,
|
E40611D514E4E98B0065996A /* TestFlight.h */,
|
||||||
);
|
);
|
||||||
path = testflight;
|
path = testflight;
|
||||||
@@ -319,9 +318,9 @@
|
|||||||
E430D08D15F88BC70010558D /* occlusion_test.fsh in Resources */,
|
E430D08D15F88BC70010558D /* occlusion_test.fsh in Resources */,
|
||||||
28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */,
|
28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */,
|
||||||
E49EB29C13806C5D00A4E727 /* MainWindow-iPad.xib in Resources */,
|
E49EB29C13806C5D00A4E727 /* MainWindow-iPad.xib in Resources */,
|
||||||
E40611D714E4E98B0065996A /* README.txt in Resources */,
|
|
||||||
E40611D814E4E98B0065996A /* release_notes.txt in Resources */,
|
|
||||||
E4CE184A15FEEE8500F80870 /* font.pvr in Resources */,
|
E4CE184A15FEEE8500F80870 /* font.pvr in Resources */,
|
||||||
|
E48BB5F9160AEF16008477A6 /* README.md in Resources */,
|
||||||
|
E48BB5FA160AEF16008477A6 /* release_notes.md in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -336,11 +335,6 @@
|
|||||||
1D3623260D0F684500981E51 /* KRObjViewAppDelegate.mm in Sources */,
|
1D3623260D0F684500981E51 /* KRObjViewAppDelegate.mm in Sources */,
|
||||||
28D7ACF80DDB3853001CB0EB /* KRObjViewViewController.mm in Sources */,
|
28D7ACF80DDB3853001CB0EB /* KRObjViewViewController.mm in Sources */,
|
||||||
1063FC77136D6A1B00EE555B /* KRObjViewGLView.mm in Sources */,
|
1063FC77136D6A1B00EE555B /* KRObjViewGLView.mm in Sources */,
|
||||||
E430D08615F88A9F0010558D /* occlusion_test.fsh in Sources */,
|
|
||||||
E430D08B15F88B950010558D /* occlusion_test.vsh in Sources */,
|
|
||||||
E48839A415F92C6900BD66D5 /* visualize_overlay.fsh in Sources */,
|
|
||||||
E4CE185215FF12A700F80870 /* light_point_inside.fsh in Sources */,
|
|
||||||
E4CE185315FF12A700F80870 /* light_point_inside.vsh in Sources */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -365,7 +359,6 @@
|
|||||||
LIBRARY_SEARCH_PATHS = (
|
LIBRARY_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"\"$(SRCROOT)\"",
|
"\"$(SRCROOT)\"",
|
||||||
"\"$(SRCROOT)/TestFlightSDK0.8\"",
|
|
||||||
"\"$(SRCROOT)/testflight\"",
|
"\"$(SRCROOT)/testflight\"",
|
||||||
);
|
);
|
||||||
PRODUCT_NAME = KRObjView3;
|
PRODUCT_NAME = KRObjView3;
|
||||||
@@ -391,7 +384,6 @@
|
|||||||
LIBRARY_SEARCH_PATHS = (
|
LIBRARY_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"\"$(SRCROOT)\"",
|
"\"$(SRCROOT)\"",
|
||||||
"\"$(SRCROOT)/TestFlightSDK0.8\"",
|
|
||||||
"\"$(SRCROOT)/testflight\"",
|
"\"$(SRCROOT)/testflight\"",
|
||||||
);
|
);
|
||||||
PRODUCT_NAME = KRObjView3;
|
PRODUCT_NAME = KRObjView3;
|
||||||
@@ -457,7 +449,6 @@
|
|||||||
LIBRARY_SEARCH_PATHS = (
|
LIBRARY_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"\"$(SRCROOT)\"",
|
"\"$(SRCROOT)\"",
|
||||||
"\"$(SRCROOT)/TestFlightSDK0.8\"",
|
|
||||||
"\"$(SRCROOT)/testflight\"",
|
"\"$(SRCROOT)/testflight\"",
|
||||||
);
|
);
|
||||||
PRODUCT_NAME = KRObjView3;
|
PRODUCT_NAME = KRObjView3;
|
||||||
|
|||||||
@@ -1,22 +1,4 @@
|
|||||||
Thanks for downloading the TestFlight SDK 0.8.2!
|
##Introduction
|
||||||
|
|
||||||
This document is also available on the web at https://www.testflightapp.com/sdk/doc
|
|
||||||
|
|
||||||
1. Why use the TestFlight SDK?
|
|
||||||
2. Considerations
|
|
||||||
3. How do I integrate the SDK into my project?
|
|
||||||
4. Using the Checkpoint API
|
|
||||||
5. Using the Feedback API
|
|
||||||
6. Upload your build
|
|
||||||
7. Questions API
|
|
||||||
8. View your results
|
|
||||||
9. Advanced Exception Handling
|
|
||||||
10. Remote Logging
|
|
||||||
|
|
||||||
START
|
|
||||||
|
|
||||||
|
|
||||||
1. Why use the TestFlight SDK?
|
|
||||||
|
|
||||||
The TestFlight SDK allows you to track how beta testers are testing your application. Out of the box we track simple usage information, such as which tester is using your application, their device model/OS, how long they used the application, logs of their test session, and automatic recording of any crashes they encounter.
|
The TestFlight SDK allows you to track how beta testers are testing your application. Out of the box we track simple usage information, such as which tester is using your application, their device model/OS, how long they used the application, logs of their test session, and automatic recording of any crashes they encounter.
|
||||||
|
|
||||||
@@ -28,141 +10,169 @@ Alongside the Checkpoint API is the Questions interface. The Questions interface
|
|||||||
|
|
||||||
For more detailed debugging we have a remote logging solution. Find out more about our logging system with TFLog in the Remote Logging section.
|
For more detailed debugging we have a remote logging solution. Find out more about our logging system with TFLog in the Remote Logging section.
|
||||||
|
|
||||||
2. Considerations
|
|
||||||
|
|
||||||
|
|
||||||
|
##Considerations
|
||||||
|
|
||||||
Information gathered by the SDK is sent to the website in real time. When an application is put into the background (iOS 4.x) or terminated (iOS 3.x) we try to send the finalizing information for the session during the time allowed for finalizing the application. Should all of the data not get sent the remaining data will be sent the next time the application is launched. As such, to get the most out of the SDK we recommend your application support iOS 4.0 and higher.
|
Information gathered by the SDK is sent to the website in real time. When an application is put into the background (iOS 4.x) or terminated (iOS 3.x) we try to send the finalizing information for the session during the time allowed for finalizing the application. Should all of the data not get sent the remaining data will be sent the next time the application is launched. As such, to get the most out of the SDK we recommend your application support iOS 4.0 and higher.
|
||||||
|
|
||||||
This SDK can be run from both the iPhone Simulator and Device and has been tested using Xcode 4.0.
|
This SDK can be run from both the iPhone Simulator and Device and has been tested using Xcode 4.0.
|
||||||
|
|
||||||
3. How do I integrate the SDK into my project?
|
|
||||||
|
##Integration
|
||||||
|
|
||||||
1. Add the files to your project: File -> Add Files to "<your project name>"
|
|
||||||
|
|
||||||
|
1. Add the files to your project: File -> Add Files to " "
|
||||||
1. Find and select the folder that contains the SDK
|
1. Find and select the folder that contains the SDK
|
||||||
2. Make sure that "Copy items into destination folder (if needed)" is checked
|
2. Make sure that "Copy items into destination folder (if needed)" is checked
|
||||||
3. Set Folders to "Create groups for any added folders"
|
3. Set Folders to "Create groups for any added folders"
|
||||||
4. Select all targets that you want to add the SDK to
|
4. Select all targets that you want to add the SDK to
|
||||||
|
2. Verify that libTestFlight.a has been added to the Link Binary With Libraries Build Phase for the targets you want to use the SDK with
|
||||||
2. Verify that libTestFlight.a has been added to the Link Binary With Libraries Build Phase for the targets you want to use the SDK with
|
|
||||||
|
|
||||||
1. Select your Project in the Project Navigator
|
1. Select your Project in the Project Navigator
|
||||||
2. Select the target you want to enable the SDK for
|
2. Select the target you want to enable the SDK for
|
||||||
3. Select the Build Phases tab
|
3. Select the Build Phases tab
|
||||||
4. Open the Link Binary With Libraries Phase
|
4. Open the Link Binary With Libraries Phase
|
||||||
5. If libTestFlight.a is not listed, drag and drop the library from your Project Navigator to the Link Binary With Libraries area
|
5. If libTestFlight.a is not listed, drag and drop the library from your Project Navigator to the Link Binary With Libraries area
|
||||||
6. Repeat Steps 2 - 5 until all targets you want to use the SDK with have the SDK linked
|
6. Repeat Steps 2 - 5 until all targets you want to use the SDK with have the SDK linked
|
||||||
|
3. Add libz to your Link Binary With Libraries Build Phase
|
||||||
|
1. Select your Project in the Project Navigator
|
||||||
|
2. Select the target you want to enable the SDK for
|
||||||
|
3. Select the Build Phases tab
|
||||||
|
4. Open the Link Binary With Libraries Phase
|
||||||
|
5. Click the + to add a new library
|
||||||
|
6. Find libz.dylib in the list and add it
|
||||||
|
7. Repeat Steps 2 - 6 until all targets you want to use the SDK with have libz.dylib
|
||||||
|
|
||||||
|
4. In your Application Delegate:
|
||||||
|
1. Import TestFlight: `#import "TestFlight.h"`
|
||||||
|
|
||||||
3. In your Application Delegate:
|
***NOTE:*** Rather than importing `TestFlight.h` in every file you may add the above line into you pre-compiled header (`<projectname>_Prefix.pch`) file inside of the
|
||||||
|
|
||||||
1. Import TestFlight: `#import "TestFlight.h"`
|
|
||||||
NOTE: If you do not want to import TestFlight.h in every file you may add the above line into you pre-compiled header (`<projectname>_Prefix.pch`) file inside of the
|
|
||||||
|
|
||||||
#ifdef __OBJC__ section.
|
#ifdef __OBJC__
|
||||||
This will give you access to the SDK across all files.
|
|
||||||
|
|
||||||
2. Get your Team Token which you can find at [http://testflightapp.com/dashboard/team/](http://testflightapp.com/dashboard/team/) select the team you are using from the team selection drop down list on the top of the page and then select edit.
|
|
||||||
|
|
||||||
|
|
||||||
|
section. This will give you access to the SDK across all files.
|
||||||
|
|
||||||
|
2. Get your Team Token which you can find at [http://testflightapp.com/dashboard/team/](http://testflightapp.com/dashboard/team/) select the team you are using from the team selection drop down list on the top of the page and then select Team Info.
|
||||||
|
|
||||||
3. Launch TestFlight with your Team Token
|
3. Launch TestFlight with your Team Token
|
||||||
|
|
||||||
-(BOOL)application:(UIApplication *)application
|
-(BOOL)application:(UIApplication *)application
|
||||||
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||||
// start of your application:didFinishLaunchingWithOptions
|
// start of your application:didFinishLaunchingWithOptions
|
||||||
// ...
|
// ...
|
||||||
[TestFlight takeOff:@"Insert your Team Token here"];
|
[TestFlight takeOff:@"Insert your Team Token here"];
|
||||||
// The rest of your application:didFinishLaunchingWithOptions method
|
// The rest of your application:didFinishLaunchingWithOptions method
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
4. To report crashes to you we install our own uncaught exception handler. If you are not currently using an exception handler of your own then all you need to do is go to the next step. If you currently use an Exception Handler, or you use another framework that does please go to the section on advanced exception handling.
|
4. To report crashes to you we install our own uncaught exception handler. If you are not currently using an exception handler of your own then all you need to do is go to the next step. If you currently use an Exception Handler, or you use another framework that does please go to the section on advanced exception handling.
|
||||||
|
|
||||||
4. To enable the best crash reporting possible we recommend setting the following project build settings in Xcode to NO for all targets that you want to have live crash reporting for. You can find build settings by opening the Project Navigator (default command+1 or command+shift+j) then clicking on the project you are configuring (usually the first selection in the list). From there you can choose to either change the global project settings or settings on an individual project basis. All settings below are in the Deployment Section.
|
5. To enable the best crash reporting possible we recommend setting the following project build settings in Xcode to NO for all targets that you want to have live crash reporting for. You can find build settings by opening the Project Navigator (default command+1 or command+shift+j) then clicking on the project you are configuring (usually the first selection in the list). From there you can choose to either change the global project settings or settings on an individual project basis. All settings below are in the Deployment Section.
|
||||||
|
|
||||||
1. Deployment Post Processing
|
1. Deployment Post Processing
|
||||||
2. Strip Debug Symbols During Copy
|
2. Strip Debug Symbols During Copy
|
||||||
3. Strip Linked Product
|
3. Strip Linked Product
|
||||||
|
|
||||||
4. Use the Checkpoint API to create important checkpoints throughout your application.
|
##Beta Testing and Release Differentiation
|
||||||
|
|
||||||
When a tester does something you care about in your app you can pass a checkpoint. For example completing a level, adding a todo item, etc. The checkpoint progress is used to provide insight into how your testers are testing your apps. The passed checkpoints are also attached to crashes, which can help when creating steps to replicate.
|
In order to provide more information about your testers while beta testing you will need to provide the device's unique identifier. This identifier is not something that the SDK will collect from the device and we do not recommend using this in production. To send the device identifier to us put the following code before your call to takeOff.
|
||||||
|
|
||||||
`[TestFlight passCheckpoint:@"CHECKPOINT_NAME"];`
|
#define TESTING 1
|
||||||
Use `passCheckpoint:` to track when a user performs certain tasks in your application. This can be useful for making sure testers are hitting all parts of your application, as well as tracking which testers are being thorough.
|
#ifdef TESTING
|
||||||
|
[TestFlight setDeviceIdentifier:[[UIDevice currentDevice] uniqueIdentifier]];
|
||||||
|
#endif
|
||||||
|
|
||||||
5. Using the Feedback API
|
This will allow you to have the best possible information during testing, but disable getting and sending of the device unique identifier when you release your application. When it is time to release simply comment out #define TESTING 1. If you decide to not include the device's unique identifier during your testing phase TestFlight will still collect all of the information that you send but it may be anonymized.
|
||||||
|
|
||||||
To launch unguided feedback call the `openFeedbackView` method. We recommend that you call this from a GUI element.
|
|
||||||
|
##Checkpoint API
|
||||||
|
|
||||||
|
When a tester does something you care about in your app you can pass a checkpoint. For example completing a level, adding a todo item, etc. The checkpoint progress is used to provide insight into how your testers are testing your apps. The passed checkpoints are also attached to crashes, which can help when creating steps to replicate.
|
||||||
|
|
||||||
|
`[TestFlight passCheckpoint:@"CHECKPOINT_NAME"];` Use `passCheckpoint:` to track when a user performs certain tasks in your application. This can be useful for making sure testers are hitting all parts of your application, as well as tracking which testers are being thorough.
|
||||||
|
|
||||||
|
##Feedback API
|
||||||
|
|
||||||
|
To launch unguided feedback call the openFeedbackView method. We recommend that you call this from a GUI element.
|
||||||
|
|
||||||
-(IBAction)launchFeedback {
|
-(IBAction)launchFeedback {
|
||||||
[TestFlight openFeedbackView];
|
[TestFlight openFeedbackView];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
If you want to create your own feedback form you can use the submitCustomFeedback method to submit the feedback that the user has entered.
|
||||||
|
|
||||||
|
-(IBAction)submitFeedbackPressed:(id)sender {
|
||||||
|
NSString *feedback = [self getUserFeedback];
|
||||||
|
[TestFlight submitFeedback:feedback];
|
||||||
|
}
|
||||||
|
|
||||||
|
The above sample assumes that [self getUserFeedback] is implemented such that it obtains the users feedback from the GUI element you have created and that submitFeedbackPressed is the action for your submit button.
|
||||||
|
|
||||||
Once users have submitted feedback from inside of the application you can view it in the feedback area of your build page.
|
Once users have submitted feedback from inside of the application you can view it in the feedback area of your build page.
|
||||||
|
|
||||||
6. Upload your build.
|
|
||||||
|
|
||||||
After you have integrated the SDK into your application you need to upload your build to TestFlight. You can upload from your dashboard or or using the Upload API, full documentation at <https://testflightapp.com/api/doc/>
|
##Upload your build
|
||||||
|
|
||||||
|
After you have integrated the SDK into your application you need to upload your build to TestFlight. You can upload from your dashboard or or using the Upload API, full documentation at [https://testflightapp.com/api/doc/](https://testflightapp.com/api/doc/)
|
||||||
|
|
||||||
7. Add Questions to Checkpoints
|
##Questions Interface
|
||||||
|
|
||||||
In order to ask a question, you'll need to associate it with a checkpoint. Make sure your checkpoints are initialized by running your app and hitting them all yourself before you start adding questions.
|
In order to ask a question, you'll need to associate it with a checkpoint. Make sure your checkpoints are initialized by running your app and hitting them all yourself before you start adding questions.
|
||||||
|
|
||||||
There are three question types available: Yes/No, Multiple Choice, and Long Answer.
|
There are three question types available: Yes/No, Multiple Choice, and Long Answer.
|
||||||
|
|
||||||
To create questions, visit your builds Questions page and click on 'Add Question'. If you choose Multiple Choice, you'll need to enter a list of possible answers for your testers to choose from — otherwise, you'll only need to enter your question's, well, question. If your build has no questions, you can also choose to migrate questions from another build (because seriously — who wants to do all that typing again)?
|
To create questions, visit your builds Questions page and click on 'Add Question'. If you choose Multiple Choice, you'll need to enter a list of possible answers for your testers to choose from — otherwise, you'll only need to enter your question's, well, question. If your build has no questions, you can also choose to migrate questions from another build (because seriously — who wants to do all that typing again)?
|
||||||
|
|
||||||
After restarting your application on an approved device, when you pass the checkpoint associated with your questions a TestFlight modal question form will appear on the screen asking the beta tester to answer your question.
|
After restarting your application on an approved device, when you pass the checkpoint associated with your questions a TestFlight modal question form will appear on the screen asking the beta tester to answer your question.
|
||||||
|
|
||||||
After you upload a new build to TestFlight you will need to associate questions once again. However if your checkpoints and questions have remained the same you can choose "copy questions from an older build" and choose which build to copy the questions from.
|
After you upload a new build to TestFlight you will need to associate questions once again. However if your checkpoints and questions have remained the same you can choose "copy questions from an older build" and choose which build to copy the questions from.
|
||||||
|
|
||||||
8. View your results.
|
##View the results
|
||||||
|
|
||||||
As testers install your build and start to test it you will see their session data on the web on the build report page for the build you've uploaded.
|
As testers install your build and start to test it you will see their session data on the web on the build report page for the build you've uploaded.
|
||||||
|
|
||||||
9. Advanced Exception Handling
|
##Advanced Exception Handling
|
||||||
|
|
||||||
An uncaught exception means that your application is in an unknown state and there is not much that you can do but try and exit gracefully. Our SDK does its best to get the data we collect in this situation to you while it is crashing, but it is designed in such a way that the important act of saving the data occurs in as safe way a way as possible before trying to send anything. If you do use uncaught exception or signal handlers install your handlers before calling `takeOff`. Our SDK will then call your handler while ours is running. For example:
|
An uncaught exception means that your application is in an unknown state and there is not much that you can do but try and exit gracefully. Our SDK does its best to get the data we collect in this situation to you while it is crashing, but it is designed in such a way that the important act of saving the data occurs in as safe way a way as possible before trying to send anything. If you do use uncaught exception or signal handlers install your handlers before calling `takeOff`. Our SDK will then call your handler while ours is running. For example:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
My Apps Custom uncaught exception catcher, we do special stuff here, and TestFlight takes care of the rest
|
My Apps Custom uncaught exception catcher, we do special stuff here, and TestFlight takes care of the rest
|
||||||
**/
|
*/
|
||||||
void HandleExceptions(NSException *exception) {
|
void HandleExceptions(NSException *exception) {
|
||||||
NSLog(@"This is where we save the application data during a exception");
|
NSLog(@"This is where we save the application data during a exception");
|
||||||
// Save application data on crash
|
// Save application data on crash
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
My Apps Custom signal catcher, we do special stuff here, and TestFlight takes care of the rest
|
My Apps Custom signal catcher, we do special stuff here, and TestFlight takes care of the rest
|
||||||
**/
|
*/
|
||||||
void SignalHandler(int sig) {
|
void SignalHandler(int sig) {
|
||||||
NSLog(@"This is where we save the application data during a signal");
|
NSLog(@"This is where we save the application data during a signal");
|
||||||
// Save application data on crash
|
// Save application data on crash
|
||||||
}
|
}
|
||||||
|
|
||||||
-(BOOL)application:(UIApplication *)application
|
-(BOOL)application:(UIApplication *)application
|
||||||
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||||
// installs HandleExceptions as the Uncaught Exception Handler
|
// installs HandleExceptions as the Uncaught Exception Handler
|
||||||
NSSetUncaughtExceptionHandler(&HandleExceptions);
|
NSSetUncaughtExceptionHandler(&HandleExceptions);
|
||||||
// create the signal action structure
|
// create the signal action structure
|
||||||
struct sigaction newSignalAction;
|
struct sigaction newSignalAction;
|
||||||
// initialize the signal action structure
|
// initialize the signal action structure
|
||||||
memset(&newSignalAction, 0, sizeof(newSignalAction));
|
memset(&newSignalAction, 0, sizeof(newSignalAction));
|
||||||
// set SignalHandler as the handler in the signal action structure
|
// set SignalHandler as the handler in the signal action structure
|
||||||
newSignalAction.sa_handler = &SignalHandler;
|
newSignalAction.sa_handler = &SignalHandler;
|
||||||
// set SignalHandler as the handlers for SIGABRT, SIGILL and SIGBUS
|
// set SignalHandler as the handlers for SIGABRT, SIGILL and SIGBUS
|
||||||
sigaction(SIGABRT, &newSignalAction, NULL);
|
sigaction(SIGABRT, &newSignalAction, NULL);
|
||||||
sigaction(SIGILL, &newSignalAction, NULL);
|
sigaction(SIGILL, &newSignalAction, NULL);
|
||||||
sigaction(SIGBUS, &newSignalAction, NULL);
|
sigaction(SIGBUS, &newSignalAction, NULL);
|
||||||
// Call takeOff after install your own unhandled exception and signal handlers
|
// Call takeOff after install your own unhandled exception and signal handlers
|
||||||
[TestFlight takeOff:@"Insert your Team Token here"];
|
[TestFlight takeOff:@"Insert your Team Token here"];
|
||||||
// continue with your application initialization
|
// continue with your application initialization
|
||||||
}
|
}
|
||||||
|
|
||||||
You do not need to add the above code if your application does not use exception handling already.
|
You do not need to add the above code if your application does not use exception handling already.
|
||||||
|
|
||||||
10. Remote Logging
|
##Remote Logging
|
||||||
|
|
||||||
To perform remote logging you can use the TFLog method which logs in a few different methods described below. In order to make the transition from NSLog to TFLog easy we have used the same method signature for TFLog as NSLog. You can easily switch over to TFLog by adding the following macro to your header
|
To perform remote logging you can use the TFLog method which logs in a few different methods described below. In order to make the transition from NSLog to TFLog easy we have used the same method signature for TFLog as NSLog. You can easily switch over to TFLog by adding the following macro to your header
|
||||||
|
|
||||||
#define NSLog TFLog
|
#define NSLog TFLog
|
||||||
@@ -183,17 +193,33 @@ We have implemented three different loggers.
|
|||||||
|
|
||||||
Each of the loggers log asynchronously and all TFLog calls are non blocking. The TestFlight logger writes its data to a file which is then sent to our servers on Session End events. The Apple System Logger sends its messages to the Apple System Log and are viewable using the Organizer in Xcode when the device is attached to your computer. The ASL logger can be disabled by turning it off in your TestFlight options
|
Each of the loggers log asynchronously and all TFLog calls are non blocking. The TestFlight logger writes its data to a file which is then sent to our servers on Session End events. The Apple System Logger sends its messages to the Apple System Log and are viewable using the Organizer in Xcode when the device is attached to your computer. The ASL logger can be disabled by turning it off in your TestFlight options
|
||||||
|
|
||||||
[TestFlight setOptions:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:@"logsToConsole"]];
|
[TestFlight setOptions:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:@"logToConsole"]];
|
||||||
|
|
||||||
The default option is YES.
|
The default option is YES.
|
||||||
|
|
||||||
The STDERR logger sends log messages to STDERR so that you can see your log statements while debugging. The STDERR logger is only active when a debugger is attached to your application.
|
The STDERR logger sends log messages to STDERR so that you can see your log statements while debugging. The STDERR logger is only active when a debugger is attached to your application. If you do not wish to use the STDERR logger you can disable it by turning it off in your TestFlight options
|
||||||
|
|
||||||
END
|
[TestFlight setOptions:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:@"logToSTDERR"]];
|
||||||
|
|
||||||
Please contact us if you have any questions.
|
The default option is YES.
|
||||||
|
|
||||||
The TestFlight Team
|
## Advanced Remote Logging
|
||||||
|
|
||||||
w. http://www.testflightapp.com
|
For most users we expect using TFLog to provide all of the logging functionality that they need. For the occasion where you need to provide a wrapper around TFLog we provide
|
||||||
e. beta@testflightapp.com
|
|
||||||
|
void TFLogv(NSString *format, va_list arg_list);
|
||||||
|
|
||||||
|
Using TFLogv you can have your method that accepts a variable number of arguments that then passes that format and argument list to TFLog.
|
||||||
|
|
||||||
|
|
||||||
|
##iOS3
|
||||||
|
|
||||||
|
We now require that anyone who is writing an application that supports iOS3 add the System.framework as an optional link. In order to provide a better shutdown experience we send any large log files to our servers in the background. To add System.framework as an optional link:
|
||||||
|
|
||||||
|
1. Select your Project in the Project Navigator
|
||||||
|
2. Select the target you want to enable the SDK for
|
||||||
|
3. Select the Build Phases tab
|
||||||
|
4. Open the Link Binary With Libraries Phase
|
||||||
|
5. Click the + to add a new library
|
||||||
|
6. Find libSystem.dylib in the list and add it
|
||||||
|
7. To the right of libSystem.dylib in the Link Binary With Libraries pane change "Required" to "Optional"
|
||||||
@@ -3,16 +3,17 @@
|
|||||||
// libTestFlight
|
// libTestFlight
|
||||||
//
|
//
|
||||||
// Created by Jonathan Janzen on 06/11/11.
|
// Created by Jonathan Janzen on 06/11/11.
|
||||||
// Copyright 2012 TestFlight. All rights reserved.
|
// Copyright 2011 TestFlight. All rights reserved.
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#define TESTFLIGHT_SDK_VERSION @"0.8.2"
|
#define TESTFLIGHT_SDK_VERSION @"1.1"
|
||||||
#undef TFLog
|
#undef TFLog
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
void TFLog(NSString *format, ...);
|
void TFLog(NSString *format, ...);
|
||||||
|
void TFLogv(NSString *format, va_list arg_list);
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -51,8 +52,14 @@ extern "C" {
|
|||||||
* library installs crash handlers overtop of the TestFlight Crash Handlers
|
* library installs crash handlers overtop of the TestFlight Crash Handlers
|
||||||
* logToConsole [ NSNumber numberWithBool:YES ] YES - default, sends log statements to Apple System Log and TestFlight log
|
* logToConsole [ NSNumber numberWithBool:YES ] YES - default, sends log statements to Apple System Log and TestFlight log
|
||||||
* NO - sends log statements to TestFlight log only
|
* NO - sends log statements to TestFlight log only
|
||||||
* sendLogOnlyOnCrash [ NSNumber numberWithBool:YES ] NO - default, sends logs to TestFlight at the end of every session
|
* logToSTDERR [ NSNumber numberWithBool:YES ] YES - default, sends log statements to STDERR when debugger is attached
|
||||||
|
* NO - sends log statements to TestFlight log only
|
||||||
|
* sendLogOnlyOnCrash [ NSNumber numberWithBool:YES ] NO - default, sends logs to TestFlight at the end of every session
|
||||||
* YES - sends logs statements to TestFlight only if there was a crash
|
* YES - sends logs statements to TestFlight only if there was a crash
|
||||||
|
* attachBacktraceToFeedback [ NSNumber numberWithBool:YES ] NO - default, feedback is sent exactly as the user enters it
|
||||||
|
* YES - attaches the current backtrace, with symbols, to the feedback.
|
||||||
|
* disableInAppUpdates [ NSNumber numberWithBool:YES ] NO - default, in application updates are allowed
|
||||||
|
* YES - the in application update screen will not be displayed
|
||||||
*/
|
*/
|
||||||
+ (void)setOptions:(NSDictionary*)options;
|
+ (void)setOptions:(NSDictionary*)options;
|
||||||
|
|
||||||
@@ -68,4 +75,27 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
+ (void)openFeedbackView;
|
+ (void)openFeedbackView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Submits custom feedback to the site. Sends the data in feedback to the site. This is to be used as the method to submit
|
||||||
|
* feedback from custom feedback forms.
|
||||||
|
*
|
||||||
|
* @param feedback Your users feedback, method does nothing if feedback is nil
|
||||||
|
*/
|
||||||
|
+ (void)submitFeedback:(NSString*)feedback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the Device Identifier.
|
||||||
|
* The SDK no longer obtains the device unique identifier. This method should only be used during testing so that you can
|
||||||
|
* identify a testers test data with them. If you do not provide the identifier you will still see all session data, with checkpoints
|
||||||
|
* and logs, but the data will be anonymized.
|
||||||
|
* It is recommended that you only use this method during testing. We also recommended that you wrap this method with a pre-processor
|
||||||
|
* directive that is only active for non-app store builds.
|
||||||
|
* #ifndef RELEASE
|
||||||
|
* [TestFlight setDeviceIdentifier:[[UIDevice currentDevice] uniqueIdentifier]];
|
||||||
|
* #endif
|
||||||
|
*
|
||||||
|
* @param deviceIdentifer The current devices device identifier
|
||||||
|
*/
|
||||||
|
+ (void)setDeviceIdentifier:(NSString*)deviceIdentifer;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
199
objview/testflight/release_notes.md
Normal file
199
objview/testflight/release_notes.md
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
##1.1 - September 13, 2012
|
||||||
|
|
||||||
|
* armv7s and iOS 6 support
|
||||||
|
* Updated for general release
|
||||||
|
|
||||||
|
##1.1 BETA 3 - September 12, 2012
|
||||||
|
|
||||||
|
* armv7s slice added to library
|
||||||
|
* fixed typo for in application updates, inAppUdates changed to inAppUpdates
|
||||||
|
|
||||||
|
##1.1 BETA 2 - September 6, 2012
|
||||||
|
|
||||||
|
* Re-enabled armv6 support
|
||||||
|
* Added option to disable in application updates
|
||||||
|
|
||||||
|
##1.1 BETA 1 - July 13, 2012
|
||||||
|
|
||||||
|
* Added TFLogv to allow for log customizations. Check the README or online docs for more information.
|
||||||
|
* Added option attachBacktraceToFeedback, which attaches a backtrace to feedback sent from the SDK. For users who use feedback in more than one location in the application.
|
||||||
|
* Resolved issue where other exception handlers would not be called during an exception.
|
||||||
|
* SDK now sends the device language for a session.
|
||||||
|
* Documentation fixes.
|
||||||
|
* Stability fixes.
|
||||||
|
|
||||||
|
###1.0 - March 29, 2012
|
||||||
|
|
||||||
|
* Resolved occurrences of exceptions with the message "No background task exists with identifier 0"
|
||||||
|
|
||||||
|
###1.0 BETA 1 - March 23, 2012
|
||||||
|
|
||||||
|
* Privacy Updates
|
||||||
|
* UDID is no longer collected by the SDK. During testing please use `[TestFlight setDeviceIdentifier:[[UIDevice currentDevice] uniqueIdentifier]];` to send the UDID so you can identify your testers. For release do not set `+setDeviceIdentifier`. See Beta Testing and Release Differentiation in the README or online at [https://testflightapp.com/sdk/doc/1.0beta1/](http://testflightapp.com/sdk/doc/1.0beta1/)
|
||||||
|
|
||||||
|
###0.8.3 - February 14, 2012
|
||||||
|
|
||||||
|
* Rolled previous beta code into release builds
|
||||||
|
* No longer allow in application updates to occur in applications that were obtained from the app store.
|
||||||
|
|
||||||
|
**Tested compiled library with:**
|
||||||
|
|
||||||
|
* Xcode 4.3
|
||||||
|
* Xcode 4.2
|
||||||
|
* Xcode 4.1
|
||||||
|
* Xcode 3.2.6
|
||||||
|
|
||||||
|
###0.8.3 BETA 5 - February 10, 2012
|
||||||
|
|
||||||
|
* Changed logging from asynchronous to synchronous.
|
||||||
|
* Resolved crash when looking for a log path failed.
|
||||||
|
* Added submitFeedback to the TestFlight class to allow for custom feedback forms.
|
||||||
|
|
||||||
|
###0.8.3 BETA 4 - January 20, 2012
|
||||||
|
|
||||||
|
* Resolved an issue that occured when an application was upgraded from 0.8.3 BETA 1 to 0.8.3 BETA 3+ with unsent data from 0.8.3 BETA 1
|
||||||
|
|
||||||
|
###0.8.3 BETA 3 - January 19, 2012
|
||||||
|
|
||||||
|
* On crash log files over 64k will not be sent until next launch.
|
||||||
|
|
||||||
|
**Known Issues:**
|
||||||
|
|
||||||
|
* Logging massive amounts of data at the end of a session may prevent the application from launching in time on next launch
|
||||||
|
|
||||||
|
###0.8.3 BETA 2 - January 13, 2012
|
||||||
|
|
||||||
|
* libz.dylib is now required to be added to your "Link Binary with Libraries" build phase
|
||||||
|
* Log file compression, The compression is done on an as needed basis rather than before sending
|
||||||
|
* Changed all outgoing data from JSON to MessagePack
|
||||||
|
* Added option `logToSTDERR` to disable the `STDERR` logger
|
||||||
|
|
||||||
|
###0.8.3 BETA 1 - December 29, 2011
|
||||||
|
|
||||||
|
* In rare occurrences old session data that had not been sent to our server may have been discarded or attached to the wrong build. It is now no longer discarded
|
||||||
|
* Made sending of Session End events more robust
|
||||||
|
* Network queuing system does better bursting of unsent data
|
||||||
|
* Log files that are larger than 64K are now sent sometime after the next launch
|
||||||
|
* Log files that are larger than 16MB are no longer supported and will be replaced with a message indicating the log file was too large
|
||||||
|
* Fixed crashes while resuming from background
|
||||||
|
|
||||||
|
###0.8.2 - December 20, 2011
|
||||||
|
|
||||||
|
* Promoted 0.8.2 BETA 4 to stable
|
||||||
|
|
||||||
|
**Known Issues:**
|
||||||
|
|
||||||
|
* Under some circumstances Session End events may not be sent until the next launch.
|
||||||
|
* With large log files Session End events may take a long time to show up.
|
||||||
|
|
||||||
|
**Tested compiled library with:**
|
||||||
|
|
||||||
|
* Xcode 4.3
|
||||||
|
* Xcode 4.2
|
||||||
|
* Xcode 4.1
|
||||||
|
* Xcode 3.2.6
|
||||||
|
|
||||||
|
###0.8.2 BETA 4 - December 12, 2011
|
||||||
|
|
||||||
|
* Prevented "The string argument is NULL" from occuring during finishedHandshake in rare cases
|
||||||
|
* Resolved issue where data recorded while offline may not be sent
|
||||||
|
|
||||||
|
###0.8.2 BETA 3 - December 8, 2011
|
||||||
|
|
||||||
|
* Added auto-release pools to background setup and tear down
|
||||||
|
|
||||||
|
###0.8.2 BETA 2 - December 5, 2011
|
||||||
|
|
||||||
|
* Fixed the "pointer being freed was not allocated" bug
|
||||||
|
|
||||||
|
###0.8.1 - November 18, 2011
|
||||||
|
|
||||||
|
* Implemented TFLog logging system, see README for more information
|
||||||
|
* Fixed an issue where Session End events may not be sent until next launch
|
||||||
|
* Fixed an issue where duplicate events could be sent
|
||||||
|
* Fixed an issue with Session End events not being sent from some iPod touch models
|
||||||
|
|
||||||
|
**Tested compiled library with:**
|
||||||
|
|
||||||
|
* Xcode 4.2
|
||||||
|
* Xcode 4.1
|
||||||
|
* Xcode 3.2.6
|
||||||
|
|
||||||
|
###0.8 - November 8, 2011
|
||||||
|
|
||||||
|
* Added `SIGTRAP` as a signal type that we catch
|
||||||
|
* Removed all Objective-c from crash reporting
|
||||||
|
* Removed the use of non signal safe functions from signal handling
|
||||||
|
* Created a signal safe way to get symbols from a stack trace
|
||||||
|
* Changed the keyboardType for Long Answer Questions and Feedback to allow for international character input
|
||||||
|
* Changed `TESTFLIGHT_SDK_VERSION` string to be an `NSString`
|
||||||
|
* Changed cache folder from Library/Caches/TestFlight to Library/Caches/com.testflight.testflightsdk
|
||||||
|
* Fixed issue with saving data when device is offline
|
||||||
|
* Fixed compability issues with iOS 3
|
||||||
|
* Added calling into the rootViewController shouldAutorotateToInterfaceOrientation if a rootViewController is set
|
||||||
|
* Made the comments in TestFlight.h compatible with Appledoc
|
||||||
|
|
||||||
|
Tested compiled library with:
|
||||||
|
|
||||||
|
* Xcode 4.2
|
||||||
|
* Xcode 4.1
|
||||||
|
* Xcode 3.2
|
||||||
|
|
||||||
|
###0.7.2 - September 29, 2011
|
||||||
|
|
||||||
|
* Changed `TESTFLIGHT_SDK_VERSION` string to be an `NSString`
|
||||||
|
* Fixed an issue where exiting an application while the SDK is active caused modal views to be dismissed
|
||||||
|
|
||||||
|
###0.7.1 - September 22, 2011
|
||||||
|
|
||||||
|
* Internal release
|
||||||
|
* Refactoring
|
||||||
|
|
||||||
|
###0.7 - September 21, 2011
|
||||||
|
|
||||||
|
* Moved TestFlight images and data to the Library/Caches folder
|
||||||
|
* Resolved an issue where sometimes the rootViewController could not be found and feedback, questions and upgrade views would not be displayed
|
||||||
|
* In application upgrade changed to allow skipping until the next version is installed and allows upgrades to be forced
|
||||||
|
* Fixed a memory leak when launching questions
|
||||||
|
|
||||||
|
###0.6 - September 2, 2011
|
||||||
|
|
||||||
|
* Renamed base64_encode to testflight_base64_encode to remove a conflict with other third party libraries
|
||||||
|
* Added ability to reinstall crash handlers when they are overwritten using the setOptions API
|
||||||
|
* Fixed an issue where crash reports might not get sent under certain circumstances
|
||||||
|
* Fixed a deadlock when the application is put in the background and then resumed before all information can be sent
|
||||||
|
* Fixed an issue when attempting to un-install all signal handlers during a signal
|
||||||
|
* Added support for landscape mode on the iPad to the Questions and Feedback views
|
||||||
|
* Crash reporting now works in versions of Xcode earlier than 4.2
|
||||||
|
* Fixed a memory leak during handshake
|
||||||
|
|
||||||
|
###0.5 - August 19, 2011
|
||||||
|
|
||||||
|
* Feedback that is not attached to a checkpoint [TestFlight openFeedbackView]
|
||||||
|
* Usability changes to question views
|
||||||
|
* Removed pause and resume sessions, replaced with sessions being stopped and started
|
||||||
|
* Added text auto correction to the Long Answer question type
|
||||||
|
* Crash reports now send on crash instead of next launch
|
||||||
|
|
||||||
|
###0.4 - August 15, 2011
|
||||||
|
|
||||||
|
* In Application Feedback with Questions
|
||||||
|
* In application updates
|
||||||
|
* Custom Environment Information added
|
||||||
|
* Networking stack reimplementation
|
||||||
|
* Exception handling fixes
|
||||||
|
|
||||||
|
###0.3 - June 15, 2011
|
||||||
|
|
||||||
|
* Removed all mention of JSONKit from the README
|
||||||
|
* Added support for using both the Bundle Version and the Bundle Short Version string
|
||||||
|
|
||||||
|
###0.2 - June 14, 2011
|
||||||
|
|
||||||
|
* Removed all categories this allows users to use the SDK without having to set -ObjC and -load_all
|
||||||
|
* Prefixed JSONKit for use in TestFlight to remove reported issues where some users were already using JSONKit
|
||||||
|
* Added support for armv6 again
|
||||||
|
|
||||||
|
###0.1 - June 11, 2011
|
||||||
|
|
||||||
|
* Initial Version
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
0.8.2 - December 20, 2011
|
|
||||||
Promoted 0.8.2 BETA 4 to stable
|
|
||||||
|
|
||||||
Known Issues:
|
|
||||||
Under some circumstances Session End events may not be sent until the next launch.
|
|
||||||
With large log files Session End events may take a long time to show up.
|
|
||||||
|
|
||||||
Tested compiled library with
|
|
||||||
Xcode 4.3
|
|
||||||
Xcode 4.2
|
|
||||||
Xcode 4.1
|
|
||||||
Xcode 3.2.6
|
|
||||||
|
|
||||||
0.8.2 BETA 4 - December 12, 2011
|
|
||||||
Prevented "The string argument is NULL" from occuring during finishedHandshake in rare cases
|
|
||||||
Resolved issue where background data may not be sent
|
|
||||||
|
|
||||||
0.8.2 BETA 3 - December 8, 2011
|
|
||||||
Added auto-release pools to background setup and tear down
|
|
||||||
Added C++ specific code to TFLog declaration
|
|
||||||
|
|
||||||
0.8.2 BETA 2 - December 5, 2011
|
|
||||||
Fixed the "pointer being freed was not allocated" bug
|
|
||||||
|
|
||||||
0.8.1 - November 18, 2011
|
|
||||||
Implemented TFLog logging system, see README for more information
|
|
||||||
Fixed an issue where Session End events may not be sent until next launch
|
|
||||||
Fixed an issue where duplicate events could be sent
|
|
||||||
Fixed an issue with Session End events not being sent from some iPod touch models
|
|
||||||
|
|
||||||
Tested compiled library with
|
|
||||||
Xcode 4.2
|
|
||||||
Xcode 4.1
|
|
||||||
Xcode 3.2.6
|
|
||||||
|
|
||||||
0.8 - November 8, 2011
|
|
||||||
Added SIGTRAP as a signal type that we catch
|
|
||||||
Removed all Objective-c from crash reporting
|
|
||||||
Removed the use of non signal safe functions from signal handling
|
|
||||||
Created a signal safe way to get symbols from a stack trace
|
|
||||||
Changed the keyboardType for Long Answer Questions and Feedback to allow for international character input
|
|
||||||
Changed TESTFLIGHT_SDK_VERSION string to be an NSString
|
|
||||||
Changed cache folder from Library/Caches/TestFlight to Library/Caches/com.testflight.testflightsdk
|
|
||||||
Fixed issue with saving data when device is offline
|
|
||||||
Fixed compability issues with iOS 3
|
|
||||||
Added calling into the rootViewController shouldAutorotateToInterfaceOrientation if a rootViewController is set
|
|
||||||
Made the comments in TestFlight.h compatible with Appledoc
|
|
||||||
|
|
||||||
Tested compiled library with
|
|
||||||
Xcode 4.2
|
|
||||||
Xcode 4.1
|
|
||||||
Xcode 3.2
|
|
||||||
|
|
||||||
0.7.2 - September 29, 2011
|
|
||||||
Changed TESTFLIGHT_SDK_VERSION string to be an NSString
|
|
||||||
Fixed an issue where exiting an application while the SDK is active caused modal views to be dismissed
|
|
||||||
0.7.1 - September 22, 2011
|
|
||||||
Internal release
|
|
||||||
Refactoring
|
|
||||||
0.7 - September 21, 2011
|
|
||||||
Moved TestFlight images and data to the Library/Caches folder
|
|
||||||
Resolved an issue where sometimes the rootViewController could not be found and feedback, questions and upgrade views would not be displayed
|
|
||||||
In application upgrade changed to allow skipping until the next version is installed and allows upgrades to be forced
|
|
||||||
Fixed a memory leak when launching questions
|
|
||||||
0.6 - September 2, 2011
|
|
||||||
Renamed base64_encode to testflight_base64_encode to remove a conflict with other third party libraries
|
|
||||||
Added ability to reinstall crash handlers when they are overwritten using the setOptions API
|
|
||||||
Fixed an issue where crash reports might not get sent under certain circumstances
|
|
||||||
Fixed a deadlock when the application is put in the background and then resumed before all information can be sent
|
|
||||||
Fixed an issue when attempting to un-install all signal handlers during a signal
|
|
||||||
Added support for landscape mode on the iPad to the Questions and Feedback views
|
|
||||||
Crash reporting now works in versions of Xcode earlier than 4.2
|
|
||||||
Fixed a memory leak during handshake
|
|
||||||
0.5 - August 19, 2011
|
|
||||||
Feedback that is not attached to a checkpoint [TestFlight openFeedbackView]
|
|
||||||
Usability changes to question views
|
|
||||||
Removed pause and resume sessions, replaced with sessions being stopped and started
|
|
||||||
Added text auto correction to the Long Answer question type
|
|
||||||
Crash reports now send on crash instead of next launch
|
|
||||||
0.4 - August 15, 2011
|
|
||||||
In Application Feedback with Questions
|
|
||||||
In application updates
|
|
||||||
Custom Environment Information added
|
|
||||||
Networking stack reimplementation
|
|
||||||
Exception handling fixes
|
|
||||||
0.3 - June 15, 2011
|
|
||||||
Removed all mention of JSONKit from the README
|
|
||||||
Added support for using both the Bundle Version and the Bundle Short Version string
|
|
||||||
0.2 - June 14, 2011
|
|
||||||
Removed all categories this allows users to use the SDK without having to set -ObjC and -load_all
|
|
||||||
Prefixed JSONKit for use in TestFlight to remove reported issues where some users were already using JSONKit
|
|
||||||
Added support for armv6 again
|
|
||||||
0.1 - June 11, 2011
|
|
||||||
Initial Version
|
|
||||||
Reference in New Issue
Block a user