[ios] #3979 compress telemetry events (#5490)

* [ios] #3979 wip gzip telemetry events

* [ios] expose compression from core instead of adding a new dependency

* [ios] #3979 Exposed decompress from mbgl and added a test case

* [ios] #3979 cleanup

* [ios] #3979 cleaned up test case

* [ios] #3979 cleanup

* [ios] #3979 gzip -> deflate
This commit is contained in:
Fredrik Karlsson
2016-07-05 22:46:04 +02:00
committed by GitHub
parent b2197236b6
commit 546469459f
8 changed files with 138 additions and 16 deletions

View File

@@ -0,0 +1,12 @@
#pragma once
#include <string>
namespace mbgl {
namespace util {
std::string compress(const std::string& raw);
std::string decompress(const std::string& raw);
} // namespace util
} // namespace mbgl

View File

@@ -0,0 +1,15 @@
#import <Foundation/Foundation.h>
#import "MGLTypes.h"
NS_ASSUME_NONNULL_BEGIN
@interface NSData (MGLAdditions)
- (NSData *)mgl_compressedData;
- (NSData *)mgl_decompressedData;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,23 @@
#import "NSData+MGLAdditions.h"
#include <mbgl/util/compression.hpp>
@implementation NSData (MGLAdditions)
- (NSData *)mgl_compressedData
{
std::string string(static_cast<const char*>(self.bytes), self.length);
std::string compressed_string = mbgl::util::compress(string);
return [NSData dataWithBytes:&compressed_string[0] length:compressed_string.length()];
}
- (NSData *)mgl_decompressedData
{
std::string string(static_cast<const char*>(self.bytes), self.length);
std::string decompressed_string = mbgl::util::decompress(string);
return [NSData dataWithBytes:&decompressed_string[0] length:decompressed_string.length()];
}
@end

View File

@@ -7,7 +7,12 @@
objects = {
/* Begin PBXBuildFile section */
35305D481D22AA680007D005 /* NSData+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35305D471D22AA450007D005 /* NSData+MGLAdditions.mm */; };
35305D491D22AA680007D005 /* NSData+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35305D471D22AA450007D005 /* NSData+MGLAdditions.mm */; };
35305D4A1D22AA6A0007D005 /* NSData+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 35305D461D22AA450007D005 /* NSData+MGLAdditions.h */; settings = {ATTRIBUTES = (Private, ); }; };
353794D01D22B3BD002C281C /* NSData+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 35305D461D22AA450007D005 /* NSData+MGLAdditions.h */; settings = {ATTRIBUTES = (Private, ); }; };
353D23961D0B0DFE002BE09D /* MGLAnnotationViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 353D23951D0B0DFE002BE09D /* MGLAnnotationViewTests.m */; };
35E208A71D24210F00EC9A46 /* MGLNSDataAdditionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 35E208A61D24210F00EC9A46 /* MGLNSDataAdditionsTests.m */; };
4018B1C71CDC287F00F666AF /* MGLAnnotationView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4018B1C41CDC277F00F666AF /* MGLAnnotationView.mm */; };
4018B1C81CDC287F00F666AF /* MGLAnnotationView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4018B1C41CDC277F00F666AF /* MGLAnnotationView.mm */; };
4018B1C91CDC288A00F666AF /* MGLAnnotationView_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 4018B1C31CDC277F00F666AF /* MGLAnnotationView_Private.h */; };
@@ -326,7 +331,10 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
35305D461D22AA450007D005 /* NSData+MGLAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSData+MGLAdditions.h"; sourceTree = "<group>"; };
35305D471D22AA450007D005 /* NSData+MGLAdditions.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSData+MGLAdditions.mm"; sourceTree = "<group>"; };
353D23951D0B0DFE002BE09D /* MGLAnnotationViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLAnnotationViewTests.m; sourceTree = "<group>"; };
35E208A61D24210F00EC9A46 /* MGLNSDataAdditionsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLNSDataAdditionsTests.m; sourceTree = "<group>"; };
4018B1C31CDC277F00F666AF /* MGLAnnotationView_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAnnotationView_Private.h; sourceTree = "<group>"; };
4018B1C41CDC277F00F666AF /* MGLAnnotationView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLAnnotationView.mm; sourceTree = "<group>"; };
4018B1C51CDC277F00F666AF /* MGLAnnotationView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAnnotationView.h; sourceTree = "<group>"; };
@@ -647,17 +655,18 @@
DA2E88521CC036F400F24E7B /* SDK Tests */ = {
isa = PBXGroup;
children = (
DA2E88551CC036F400F24E7B /* Info.plist */,
353D23951D0B0DFE002BE09D /* MGLAnnotationViewTests.m */,
DA35A2C31CCA9F8300E826B2 /* MGLClockDirectionFormatterTests.m */,
DA35A2C41CCA9F8300E826B2 /* MGLCompassDirectionFormatterTests.m */,
DA35A2A91CCA058D00E826B2 /* MGLCoordinateFormatterTests.m */,
DA0CD58F1CF56F6A00A5F5A5 /* MGLFeatureTests.mm */,
DA2E885C1CC0382C00F24E7B /* MGLGeometryTests.mm */,
35E208A61D24210F00EC9A46 /* MGLNSDataAdditionsTests.m */,
DA2E885D1CC0382C00F24E7B /* MGLOfflinePackTests.m */,
DA2E885E1CC0382C00F24E7B /* MGLOfflineRegionTests.m */,
DA2E885F1CC0382C00F24E7B /* MGLOfflineStorageTests.m */,
353D23951D0B0DFE002BE09D /* MGLAnnotationViewTests.m */,
DA2E88601CC0382C00F24E7B /* MGLStyleTests.mm */,
DA2E88551CC036F400F24E7B /* Info.plist */,
);
name = "SDK Tests";
path = test;
@@ -895,6 +904,8 @@
children = (
DA8848121CBAFA6200AB86E3 /* NSBundle+MGLAdditions.h */,
DA8848131CBAFA6200AB86E3 /* NSBundle+MGLAdditions.m */,
35305D461D22AA450007D005 /* NSData+MGLAdditions.h */,
35305D471D22AA450007D005 /* NSData+MGLAdditions.mm */,
DA8848141CBAFA6200AB86E3 /* NSException+MGLAdditions.h */,
DA8848151CBAFA6200AB86E3 /* NSProcessInfo+MGLAdditions.h */,
DA8848161CBAFA6200AB86E3 /* NSProcessInfo+MGLAdditions.m */,
@@ -1000,6 +1011,7 @@
DA88481B1CBAFA6200AB86E3 /* MGLGeometry_Private.h in Headers */,
DA88485C1CBAFB9800AB86E3 /* MGLUserLocationAnnotationView.h in Headers */,
DA8848871CBB033F00AB86E3 /* Fabric.h in Headers */,
35305D4A1D22AA6A0007D005 /* NSData+MGLAdditions.h in Headers */,
DA8848841CBB033F00AB86E3 /* FABAttributes.h in Headers */,
DA8847FD1CBAFA5100AB86E3 /* MGLTilePyramidOfflineRegion.h in Headers */,
DA88482F1CBAFA6200AB86E3 /* NSProcessInfo+MGLAdditions.h in Headers */,
@@ -1045,6 +1057,7 @@
DABFB86E1CBE9A0F00D62B32 /* MGLCalloutView.h in Headers */,
DABFB8601CBE99E500D62B32 /* MGLMapCamera.h in Headers */,
DA737EE21D056A4E005BDA16 /* MGLMapViewDelegate.h in Headers */,
353794D01D22B3BD002C281C /* NSData+MGLAdditions.h in Headers */,
DABFB86A1CBE99E500D62B32 /* MGLStyle.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1355,6 +1368,7 @@
DA2E88621CC0382C00F24E7B /* MGLOfflinePackTests.m in Sources */,
DA35A2AA1CCA058D00E826B2 /* MGLCoordinateFormatterTests.m in Sources */,
353D23961D0B0DFE002BE09D /* MGLAnnotationViewTests.m in Sources */,
35E208A71D24210F00EC9A46 /* MGLNSDataAdditionsTests.m in Sources */,
DA0CD5901CF56F6A00A5F5A5 /* MGLFeatureTests.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1382,6 +1396,7 @@
DA35A2CB1CCAAAD200E826B2 /* NSValue+MGLAdditions.m in Sources */,
DA8848321CBAFA6200AB86E3 /* NSString+MGLAdditions.m in Sources */,
DA35A2A11CC9E95F00E826B2 /* MGLCoordinateFormatter.m in Sources */,
35305D481D22AA680007D005 /* NSData+MGLAdditions.mm in Sources */,
DA8848291CBAFA6200AB86E3 /* MGLStyle.mm in Sources */,
DA88481C1CBAFA6200AB86E3 /* MGLGeometry.mm in Sources */,
DA88481F1CBAFA6200AB86E3 /* MGLMultiPoint.mm in Sources */,
@@ -1423,6 +1438,7 @@
DA35A2CC1CCAAAD200E826B2 /* NSValue+MGLAdditions.m in Sources */,
DAA4E4281CBB730400178DFB /* MGLTypes.m in Sources */,
DA35A2A21CC9E95F00E826B2 /* MGLCoordinateFormatter.m in Sources */,
35305D491D22AA680007D005 /* NSData+MGLAdditions.mm in Sources */,
DAA4E42D1CBB730400178DFB /* MGLAnnotationImage.m in Sources */,
DAA4E4301CBB730400178DFB /* MGLLocationManager.m in Sources */,
DAA4E4321CBB730400178DFB /* MGLMapView.mm in Sources */,

View File

@@ -1,5 +1,6 @@
#import "MGLAPIClient.h"
#import "NSBundle+MGLAdditions.h"
#import "NSData+MGLAdditions.h"
#import "MGLAccountManager.h"
static NSString * const MGLAPIClientUserAgentBase = @"MapboxEventsiOS";
@@ -9,6 +10,7 @@ static NSString * const MGLAPIClientEventsPath = @"events/v2";
static NSString * const MGLAPIClientHeaderFieldUserAgentKey = @"User-Agent";
static NSString * const MGLAPIClientHeaderFieldContentTypeKey = @"Content-Type";
static NSString * const MGLAPIClientHeaderFieldContentTypeValue = @"application/json";
static NSString * const MGLAPIClientHeaderFieldContentEncodingKey = @"Content-Encoding";
static NSString * const MGLAPIClientHTTPMethodPost = @"POST";
@interface MGLAPIClient ()
@@ -82,8 +84,22 @@ static NSString * const MGLAPIClientHTTPMethodPost = @"POST";
[request setValue:self.userAgent forHTTPHeaderField:MGLAPIClientHeaderFieldUserAgentKey];
[request setValue:MGLAPIClientHeaderFieldContentTypeValue forHTTPHeaderField:MGLAPIClientHeaderFieldContentTypeKey];
[request setHTTPMethod:MGLAPIClientHTTPMethodPost];
NSData *jsonData = [self serializedDataForEvents:events];
[request setHTTPBody:jsonData];
// Compressing less than 3 events can have a negative impact on the size.
if (events.count > 2) {
NSData *compressedData = [jsonData mgl_compressedData];
[request setValue:@"deflate" forHTTPHeaderField:MGLAPIClientHeaderFieldContentEncodingKey];
[request setHTTPBody:compressedData];
}
// Set JSON data if events.count were less than 3 or something went wrong with compressing HTTP body data.
if (!request.HTTPBody) {
[request setValue:nil forHTTPHeaderField:MGLAPIClientHeaderFieldContentEncodingKey];
[request setHTTPBody:jsonData];
}
return [request copy];
}

View File

@@ -0,0 +1,52 @@
#import <XCTest/XCTest.h>
#import "../../darwin/src/NSData+MGLAdditions.h"
@interface MGLNSDataAdditionsTests : XCTestCase
@end
@implementation MGLNSDataAdditionsTests
- (void)setUp {
[super setUp];
}
- (void)testCompressDecompress
{
NSArray *originalArray = [self mockDataWithCount:180];
NSData *originalData = [NSJSONSerialization dataWithJSONObject:originalArray options:0 error:nil];
NSData *compressedData = [originalData mgl_compressedData];
NSData *decompressedData = [compressedData mgl_decompressedData];
NSArray *decompressedArray = [NSJSONSerialization JSONObjectWithData:decompressedData options:0 error:nil];
XCTAssertTrue([originalArray isEqualToArray:decompressedArray], @"originalArray and decompressedArray should be equal");
}
- (NSArray *)mockDataWithCount:(NSUInteger)count
{
NSMutableArray *array = [NSMutableArray array];
for (NSUInteger i=0;i<count;i++)
{
[array addObject:@{@"lat": @([self safeValueBetween:-90 and:90]),
@"lng": @([self safeValueBetween:-180 and:180]),
@"timestamp": @((floor([NSDate date].timeIntervalSince1970) * 100) / 100)}];
}
return array;
}
- (double)safeValueBetween:(double)lowerBound and:(double)upperBound
{
return floor([self randomBetween:lowerBound and:upperBound] * 100 ) / 100;
}
- (double)randomBetween:(double)lowerBound and:(double)upperBound
{
return lowerBound * drand48() + upperBound * drand48();
}
@end

View File

@@ -1,4 +1,4 @@
#include "compression.hpp"
#include <mbgl/util/compression.hpp>
#include <zlib.h>

View File

@@ -1,12 +0,0 @@
#pragma once
#include <string>
namespace mbgl {
namespace util {
std::string compress(const std::string &raw);
std::string decompress(const std::string &raw);
} // namespace util
} // namespace mbgl