From cb627ba13b4f21f83066d206b75560d41ec52ec5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Spie=C3=9F?= Date: Fri, 22 Apr 2016 17:48:49 +0200 Subject: [PATCH 1/7] Port CoreFoundation improvements from OS X SDK Thanks again @tonklon! --- Classes/BITFeedbackMessageAttachment.m | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/Classes/BITFeedbackMessageAttachment.m b/Classes/BITFeedbackMessageAttachment.m index 7e8dfc1ab0..cc74cb2e89 100644 --- a/Classes/BITFeedbackMessageAttachment.m +++ b/Classes/BITFeedbackMessageAttachment.m @@ -220,15 +220,18 @@ // File extension that suits the Content type. CFStringRef mimeType = (__bridge CFStringRef)self.contentType; - CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeType, NULL); - CFStringRef extension = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassFilenameExtension); - if (extension) { - _tempFilename = [_tempFilename stringByAppendingPathExtension:(__bridge NSString *)(extension)]; - CFRelease(extension); + if (mimeType) { + CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeType, NULL); + CFStringRef extension = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassFilenameExtension); + if (extension) { + _tempFilename = [_tempFilename stringByAppendingPathExtension:(__bridge NSString *)(extension)]; + CFRelease(extension); + } + if (uti) { + CFRelease(uti); + } } - CFRelease(uti); - return _tempFilename; } From 60f81dcd6622631184c10ea7aec0f943a7bc3475 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Spie=C3=9F?= Date: Thu, 14 Apr 2016 02:47:12 +0200 Subject: [PATCH 2/7] Make assertions in AppIconFilename tests more precise --- Support/HockeySDKTests/BITHockeyHelperTests.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Support/HockeySDKTests/BITHockeyHelperTests.m b/Support/HockeySDKTests/BITHockeyHelperTests.m index 5f0cdc30cd..990f26faca 100644 --- a/Support/HockeySDKTests/BITHockeyHelperTests.m +++ b/Support/HockeySDKTests/BITHockeyHelperTests.m @@ -119,14 +119,14 @@ [given([mockBundle objectForInfoDictionaryKey:@"CFBundleIconFile"]) willReturn:nil]; resultString = bit_validAppIconFilename(mockBundle, resourceBundle); - assertThat(resultString, notNilValue()); + assertThat(resultString, equalTo(validIconPath2x)); // CFBundleIcons contains valid dictionary filenames [given([mockBundle objectForInfoDictionaryKey:@"CFBundleIconFiles"]) willReturn:@[@"invalidFilename.png"]]; [given([mockBundle objectForInfoDictionaryKey:@"CFBundleIcons"]) willReturn:@{@"CFBundlePrimaryIcon":@{@"CFBundleIconFiles":@[validIconPath, validIconPath2x]}}]; [given([mockBundle objectForInfoDictionaryKey:@"CFBundleIcons~ipad"]) willReturn:nil]; [given([mockBundle objectForInfoDictionaryKey:@"CFBundleIconFile"]) willReturn:nil]; - + // CFBundleIcons contains valid ipad dictionary and valid default dictionary filenames [given([mockBundle objectForInfoDictionaryKey:@"CFBundleIconFiles"]) willReturn:@[@"invalidFilename.png"]]; [given([mockBundle objectForInfoDictionaryKey:@"CFBundleIcons"]) willReturn:@{@"CFBundlePrimaryIcon":@{@"CFBundleIconFiles":@[validIconPath, validIconPath2x]}}]; @@ -134,7 +134,7 @@ [given([mockBundle objectForInfoDictionaryKey:@"CFBundleIconFile"]) willReturn:nil]; resultString = bit_validAppIconFilename(mockBundle, resourceBundle); - assertThat(resultString, notNilValue()); + assertThat(resultString, equalTo(validIconPath2x)); // CFBundleIcons contains valid filenames [given([mockBundle objectForInfoDictionaryKey:@"CFBundleIconFiles"]) willReturn:@[@"invalidFilename.png"]]; @@ -143,7 +143,7 @@ [given([mockBundle objectForInfoDictionaryKey:@"CFBundleIconFile"]) willReturn:nil]; resultString = bit_validAppIconFilename(mockBundle, resourceBundle); - assertThat(resultString, notNilValue()); + assertThat(resultString, equalTo(validIconPath2x)); // CFBundleIcon contains valid filename [given([mockBundle objectForInfoDictionaryKey:@"CFBundleIconFiles"]) willReturn:@[@"invalidFilename.png"]]; @@ -152,7 +152,7 @@ [given([mockBundle objectForInfoDictionaryKey:@"CFBundleIconFile"]) willReturn:validIconPath]; resultString = bit_validAppIconFilename(mockBundle, resourceBundle); - assertThat(resultString, notNilValue()); + assertThat(resultString, equalTo(validIconPath2x)); } - (void)testDevicePlattform { From 0eb39be3616669c8a933c8f132669e13148a1249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Spie=C3=9F?= Date: Thu, 14 Apr 2016 02:47:27 +0200 Subject: [PATCH 3/7] Add tests for exotic AppIcon filename variations --- Support/HockeySDK.xcodeproj/project.pbxproj | 18 ++++++++ ...E1AF7159-3C8D-4A2A-8625-B72024F5DD3E.plist | 22 ++++++++++ .../Info.plist | 40 ++++++++++++++++++ Support/HockeySDKTests/BITHockeyHelperTests.m | 35 ++++++++++++++- .../Fixtures/AppIcon.exotic.png | Bin 0 -> 2790 bytes .../Fixtures/AppIcon.exotic@2x.png | Bin 0 -> 3628 bytes Support/HockeySDKTests/Fixtures/Icon.png | Bin 0 -> 2790 bytes 7 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 Support/HockeySDK.xcodeproj/xcshareddata/xcbaselines/1E5A458F16F0DFC200B55C04.xcbaseline/E1AF7159-3C8D-4A2A-8625-B72024F5DD3E.plist create mode 100644 Support/HockeySDK.xcodeproj/xcshareddata/xcbaselines/1E5A458F16F0DFC200B55C04.xcbaseline/Info.plist create mode 100644 Support/HockeySDKTests/Fixtures/AppIcon.exotic.png create mode 100644 Support/HockeySDKTests/Fixtures/AppIcon.exotic@2x.png create mode 100644 Support/HockeySDKTests/Fixtures/Icon.png diff --git a/Support/HockeySDK.xcodeproj/project.pbxproj b/Support/HockeySDK.xcodeproj/project.pbxproj index eec4fafe29..99cf371126 100644 --- a/Support/HockeySDK.xcodeproj/project.pbxproj +++ b/Support/HockeySDK.xcodeproj/project.pbxproj @@ -374,6 +374,12 @@ 80807B8E1C46BF2F00F4C44F /* OCMockitoIOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 80807B8B1C46BF2F00F4C44F /* OCMockitoIOS.framework */; }; 80807B8F1C46BF2F00F4C44F /* OCMockitoIOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 80807B8B1C46BF2F00F4C44F /* OCMockitoIOS.framework */; }; 80807B901C46C01E00F4C44F /* BITUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 8034E6681BA31D7C00D83A30 /* BITUser.m */; }; + 8085BB851CBF1FA60023FD9B /* AppIcon.exotic.png in Resources */ = {isa = PBXBuildFile; fileRef = 8085BB831CBF1FA60023FD9B /* AppIcon.exotic.png */; }; + 8085BB861CBF1FA60023FD9B /* AppIcon.exotic.png in Resources */ = {isa = PBXBuildFile; fileRef = 8085BB831CBF1FA60023FD9B /* AppIcon.exotic.png */; }; + 8085BB871CBF1FA60023FD9B /* AppIcon.exotic@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8085BB841CBF1FA60023FD9B /* AppIcon.exotic@2x.png */; }; + 8085BB881CBF1FA60023FD9B /* AppIcon.exotic@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8085BB841CBF1FA60023FD9B /* AppIcon.exotic@2x.png */; }; + 8085BB8A1CBF216E0023FD9B /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 8085BB891CBF216E0023FD9B /* Icon.png */; }; + 8085BB8B1CBF216E0023FD9B /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 8085BB891CBF216E0023FD9B /* Icon.png */; }; 80A4662F1C58F4DF00199909 /* BITCrashReportTextFormatterPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 80A4662D1C58F4DF00199909 /* BITCrashReportTextFormatterPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; 80B1C4EE1C8A6F950057A5CB /* BITUser.h in Headers */ = {isa = PBXBuildFile; fileRef = 8034E6671BA31D7C00D83A30 /* BITUser.h */; }; 80B1C4EF1C8A72620057A5CB /* HockeySDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1EB6173F1B0A30480035A986 /* HockeySDK.framework */; }; @@ -687,6 +693,9 @@ 808441721C20617C00644A40 /* OCMockObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OCMockObject.h; sourceTree = ""; }; 808441731C20617C00644A40 /* OCMRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OCMRecorder.h; sourceTree = ""; }; 808441741C20617C00644A40 /* OCMStubRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OCMStubRecorder.h; sourceTree = ""; }; + 8085BB831CBF1FA60023FD9B /* AppIcon.exotic.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = AppIcon.exotic.png; sourceTree = ""; }; + 8085BB841CBF1FA60023FD9B /* AppIcon.exotic@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "AppIcon.exotic@2x.png"; sourceTree = ""; }; + 8085BB891CBF216E0023FD9B /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; 80A4662D1C58F4DF00199909 /* BITCrashReportTextFormatterPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BITCrashReportTextFormatterPrivate.h; sourceTree = ""; }; 80B1C4EB1C8A6F860057A5CB /* BITSender.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BITSender.m; sourceTree = ""; }; 80CA63881C67BD5400362DBF /* libOCMock.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libOCMock.a; sourceTree = ""; }; @@ -1009,6 +1018,9 @@ children = ( 1E494AEA19491943001EFF74 /* AppIcon.png */, 1E494AEB19491943001EFF74 /* AppIcon@2x.png */, + 8085BB831CBF1FA60023FD9B /* AppIcon.exotic.png */, + 8085BB841CBF1FA60023FD9B /* AppIcon.exotic@2x.png */, + 8085BB891CBF216E0023FD9B /* Icon.png */, 1EA1170316F53B49001C015C /* StoreBundleIdentifierUnknown.json */, 1EA1170816F53E3A001C015C /* StoreBundleIdentifierKnown.json */, 1E70A22F17F2F982001BB32D /* live_report_empty.plcrash */, @@ -1663,6 +1675,8 @@ buildActionMask = 2147483647; files = ( 1E85C5621B3438EB00CE2C0D /* live_report_exception_marketing.plcrash in Resources */, + 8085BB871CBF1FA60023FD9B /* AppIcon.exotic@2x.png in Resources */, + 8085BB851CBF1FA60023FD9B /* AppIcon.exotic.png in Resources */, 1E494AEC19491943001EFF74 /* AppIcon.png in Resources */, 1E85C5631B3438EB00CE2C0D /* live_report_signal_marketing.plcrash in Resources */, 1EA1170C16F54A64001C015C /* HockeySDKResources.bundle in Resources */, @@ -1672,6 +1686,7 @@ 1E70A23317F2F982001BB32D /* live_report_exception.plcrash in Resources */, 1E70A23217F2F982001BB32D /* live_report_empty.plcrash in Resources */, 1E494AED19491943001EFF74 /* AppIcon@2x.png in Resources */, + 8085BB8A1CBF216E0023FD9B /* Icon.png in Resources */, 1EA1170916F53E3A001C015C /* StoreBundleIdentifierKnown.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1689,6 +1704,8 @@ buildActionMask = 2147483647; files = ( 1E85C5641B3438EC00CE2C0D /* live_report_exception_marketing.plcrash in Resources */, + 8085BB881CBF1FA60023FD9B /* AppIcon.exotic@2x.png in Resources */, + 8085BB861CBF1FA60023FD9B /* AppIcon.exotic.png in Resources */, 1E1508871B0C946700D7B9D9 /* AppIcon.png in Resources */, 1E85C5651B3438EC00CE2C0D /* live_report_signal_marketing.plcrash in Resources */, 1E1508891B0C946700D7B9D9 /* StoreBundleIdentifierUnknown.json in Resources */, @@ -1698,6 +1715,7 @@ 1E15088D1B0C946700D7B9D9 /* live_report_signal.plcrash in Resources */, 1E15088A1B0C946700D7B9D9 /* StoreBundleIdentifierKnown.json in Resources */, 1E15088E1B0C946D00D7B9D9 /* InfoPlist.strings in Resources */, + 8085BB8B1CBF216E0023FD9B /* Icon.png in Resources */, 1E15088C1B0C946700D7B9D9 /* live_report_exception.plcrash in Resources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Support/HockeySDK.xcodeproj/xcshareddata/xcbaselines/1E5A458F16F0DFC200B55C04.xcbaseline/E1AF7159-3C8D-4A2A-8625-B72024F5DD3E.plist b/Support/HockeySDK.xcodeproj/xcshareddata/xcbaselines/1E5A458F16F0DFC200B55C04.xcbaseline/E1AF7159-3C8D-4A2A-8625-B72024F5DD3E.plist new file mode 100644 index 0000000000..ba52325307 --- /dev/null +++ b/Support/HockeySDK.xcodeproj/xcshareddata/xcbaselines/1E5A458F16F0DFC200B55C04.xcbaseline/E1AF7159-3C8D-4A2A-8625-B72024F5DD3E.plist @@ -0,0 +1,22 @@ + + + + + classNames + + BITHockeyHelperTests + + testValidAppIconFilenamePerformance + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.6 + baselineIntegrationDisplayName + Local Baseline + + + + + + diff --git a/Support/HockeySDK.xcodeproj/xcshareddata/xcbaselines/1E5A458F16F0DFC200B55C04.xcbaseline/Info.plist b/Support/HockeySDK.xcodeproj/xcshareddata/xcbaselines/1E5A458F16F0DFC200B55C04.xcbaseline/Info.plist new file mode 100644 index 0000000000..6a71929f22 --- /dev/null +++ b/Support/HockeySDK.xcodeproj/xcshareddata/xcbaselines/1E5A458F16F0DFC200B55C04.xcbaseline/Info.plist @@ -0,0 +1,40 @@ + + + + + runDestinationsByUUID + + E1AF7159-3C8D-4A2A-8625-B72024F5DD3E + + localComputer + + busSpeedInMHz + 100 + cpuCount + 1 + cpuKind + Intel Core i7 + cpuSpeedInMHz + 2800 + logicalCPUCoresPerPackage + 8 + modelCode + MacBookPro11,3 + physicalCPUCoresPerPackage + 4 + platformIdentifier + com.apple.platform.macosx + + targetArchitecture + x86_64 + targetDevice + + modelCode + iPhone8,1 + platformIdentifier + com.apple.platform.iphonesimulator + + + + + diff --git a/Support/HockeySDKTests/BITHockeyHelperTests.m b/Support/HockeySDKTests/BITHockeyHelperTests.m index 990f26faca..38b7c30af2 100644 --- a/Support/HockeySDKTests/BITHockeyHelperTests.m +++ b/Support/HockeySDKTests/BITHockeyHelperTests.m @@ -100,6 +100,19 @@ NSString *resultString = nil; NSBundle *mockBundle = mock([NSBundle class]); NSBundle *resourceBundle = [NSBundle bundleForClass:self.class]; + + // CFBundleIcons contains exotic dictionary filenames + NSString *exoticValidIconPath = @"AppIcon.exotic"; + NSString *exoticValidIconPath2x = @"AppIcon.exotic@2x"; + [given([mockBundle objectForInfoDictionaryKey:@"CFBundleIconFiles"]) willReturn:@[@"invalidFilename.png"]]; + [given([mockBundle objectForInfoDictionaryKey:@"CFBundleIcons"]) willReturn:@{@"CFBundlePrimaryIcon":@{@"CFBundleIconFiles":@[exoticValidIconPath, exoticValidIconPath2x]}}]; + [given([mockBundle objectForInfoDictionaryKey:@"CFBundleIcons~ipad"]) willReturn:nil]; + [given([mockBundle objectForInfoDictionaryKey:@"CFBundleIconFile"]) willReturn:nil]; + + //resultString = bit_validAppIconFilename(mockBundle, resourceBundle); + //assertThat(resultString, equalTo(exoticValidIconPath2x)); + + // Regular icon names NSString *validIconPath = @"AppIcon"; NSString *validIconPath2x = @"AppIcon@2x"; @@ -110,7 +123,7 @@ [given([mockBundle objectForInfoDictionaryKey:@"CFBundleIconFile"]) willReturn:@"invalidFilename.png"]; resultString = bit_validAppIconFilename(mockBundle, resourceBundle); - assertThat(resultString, nilValue()); + assertThat(resultString, equalTo(@"Icon")); // CFBundleIconFiles contains valid filenames [given([mockBundle objectForInfoDictionaryKey:@"CFBundleIconFiles"]) willReturn:@[validIconPath, validIconPath2x]]; @@ -155,6 +168,26 @@ assertThat(resultString, equalTo(validIconPath2x)); } +#ifndef CI +- (void)testValidAppIconFilenamePerformance { + NSBundle *mockBundle = mock([NSBundle class]); + NSBundle *resourceBundle = [NSBundle bundleForClass:self.class]; + + NSString *validIconPath2x = @"AppIcon@2x"; + + [given([mockBundle objectForInfoDictionaryKey:@"CFBundleIconFiles"]) willReturn:nil]; + [given([mockBundle objectForInfoDictionaryKey:@"CFBundleIcons"]) willReturn:nil]; + [given([mockBundle objectForInfoDictionaryKey:@"CFBundleIcons~ipad"]) willReturn:nil]; + [given([mockBundle objectForInfoDictionaryKey:@"CFBundleIconFile"]) willReturn:validIconPath2x]; + + [self measureBlock:^{ + for (int i = 0; i < 1000; i++) { + __unused NSString *resultString = bit_validAppIconFilename(mockBundle, resourceBundle); + } + }]; +} +#endif + - (void)testDevicePlattform { NSString *resultString = bit_devicePlatform(); assertThat(resultString, notNilValue()); diff --git a/Support/HockeySDKTests/Fixtures/AppIcon.exotic.png b/Support/HockeySDKTests/Fixtures/AppIcon.exotic.png new file mode 100644 index 0000000000000000000000000000000000000000..5473e5e8de977643534715d284906b506c1c58ab GIT binary patch literal 2790 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 literal 0 HcmV?d00001 diff --git a/Support/HockeySDKTests/Fixtures/Icon.png b/Support/HockeySDKTests/Fixtures/Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5473e5e8de977643534715d284906b506c1c58ab GIT binary patch literal 2790 zcmbVO2~ZPh7VdRa29Htj2qNV+QKURbx;qd^I71Rhln@Drl!DT98i*$8kTj5h3KGE* z9lQpr##sjhk77J##cL5ZIEr$(peT3@YoP;(palaAix;>Z2+SVrFtvXw-T&Y9z3+YR z=vTdOLvY~SS@yF40GKNl31rlrWBz|Wle!+TGiFh@C8RKt3?<^o6jX}?JUJ1IgJKmL zkIQgWZb+=fy#Qb)s0fQBBPBsxj8HL9Glrp8X((#|@bcAbP;5I+g0XnKLhViOEw7}5 z3b{9ZqniYhX!v-7LX@h-LsNspu+;4sM^5+k0loBGia>>vD5zH{)jF=;n?B0RrS|5> zOgcCUA-8+e$3#U+Hh_FWi-T?q$OVJg5XgoZFw525-F+>HKrqCF5GIVc!0ucY!i6Bv zvgnjItvrq^69ia%Q73PD0!eDPOlC?-3L}NZAhhvJn8V?iIS|B!Lb&J*Y7*7EsCCQ7 z83ecv(<(Hif>48IMl_a4BE9L9(y_y2`Jry01jQ6;^V#gog2x3Y ziF?zj;=wKu?1FfN!BpkkxDaOz1XCp(gGvawBF^yNP&U^U;v%m92BkVjj*{q`aY1e$<;p!WFA^B&x=6vA~;7No6P$a;{Lw5wc+q1YyBK7#2c2UVu;t zxw*N!A^`}(;g8!22rS85#Bp2suePkIY^7QS^#Y;F$v6T$+yh|P-4$|2Ahrh#d+_{) z99Iq`FiYYEc$iysv{kqwg^sF&!P4}hc%o&eRDh%1!9_811AEgkbH#8u-SSv5Nz_w% zwb-U4;1uC+lyS_n&N5|q@l=MU>JsMv(yc?2r%=tAB3Hkyngx${)c>K{LX9P$>Uf-* zflRtN4yJipjFp1IO(FSq~gwf+E(DX)%l3^r-RoDoJEbwE1QPDb+i96kVd09{qlp2TkGdM zna!eES(!Dj2UBP8vlcbwi@yR()?95--LW$6w*E=Q8fxN@Vi`O5idi&zV zi~2{8^6NP9A(>7E>+t+=?-PIh3}CR5d-E^hp@R4TRV z?CgyD{_%jz@m1|ubq4ZvP{03)LVz8zI&Vizc=)>}wBWt7^i9L3=`|a--I=`@`e-;F z9N(m5?;T8i#-4Laajm5|!#HEr-}ntTeR6|V-n#Vk+&P7P;Oerd+%pdqx%(Yu16$h9 z2k9Dz>X*^}bUD5M5^zaF@~mr0*V5`WJ9N4>V^Vo^dfJ7&;f@_@W5t4FK31ZA;9*+^ zu=j!OZf9HTZ2C%>BfmPH=Udji=gfkWBU0f(+cx&8y(j9IgD2+&d@p%Oc9q5A>falLftoxT@=B5K6JOJ)OOv2mPkM@}WeXwtNG2;AK*4@5jL5t-(%1 zt=}y=@pT_qR9PR%6%ibLcOj@gZA= zdFtu+^vo_Ei;)G->T3InRueIsD`%k^75^l^9Si1 z;%-GlQb^&_)h#V8m5I@h)2r^h?CVRMdnjU0nEX|ak|26F_xt>PaBz^RY`I{UeVFg2 z^*7mnC;?z+DWO*TY}&lpv#)?iIQHmV^R{`?;NUI9l}+~wZ#{T$zt(oK{j4QeW$DF> zeV+l9EABR@TzutgEh}l7k-Y2Nciroc2cLQA@kMc#DdSY;!k0yY`rI6ALyhaE%ZCeS z`)?Oy?v+U$etB*ay&cCpSnZEuApI^6hX Date: Thu, 14 Apr 2016 03:04:20 +0200 Subject: [PATCH 4/7] Fix AppIcon path search with exotic filenames --- Classes/BITHockeyHelper.m | 15 +++++++++------ docs/Changelog-template.md | 1 + 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Classes/BITHockeyHelper.m b/Classes/BITHockeyHelper.m index 9733dbffe7..a7b24a1c43 100644 --- a/Classes/BITHockeyHelper.m +++ b/Classes/BITHockeyHelper.m @@ -408,15 +408,20 @@ NSString *bit_validAppIconStringFromIcons(NSBundle *resourceBundle, NSArray *ico // Don't use imageNamed, otherwise unit tests won't find the fixture icon // and using imageWithContentsOfFile doesn't load @2x files with absolut paths (required in tests) - NSString *iconPathExtension = ([[icon pathExtension] length] > 0) ? [icon pathExtension] : @"png"; NSMutableArray *iconFilenameVariants = [NSMutableArray new]; + [iconFilenameVariants addObject:icon]; + [iconFilenameVariants addObject:[NSString stringWithFormat:@"%@@2x", icon]]; [iconFilenameVariants addObject:[icon stringByDeletingPathExtension]]; [iconFilenameVariants addObject:[NSString stringWithFormat:@"%@@2x", [icon stringByDeletingPathExtension]]]; for (NSString *iconFilename in iconFilenameVariants) { // this call already covers "~ipad" files - NSString *iconPath = [resourceBundle pathForResource:iconFilename ofType:iconPathExtension]; + NSString *iconPath = [resourceBundle pathForResource:iconFilename ofType:@"png"]; + + if (!iconPath && (icon.pathExtension.length > 0)) { + iconPath = [resourceBundle pathForResource:iconFilename ofType:icon.pathExtension]; + } NSData *imgData = [[NSData alloc] initWithContentsOfFile:iconPath]; @@ -453,15 +458,13 @@ NSString *bit_validAppIconFilename(NSBundle *bundle, NSBundle *resourceBundle) { } // we test iPad structure anyway and use it if we find a result and don't have another one yet - if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { + if (!iconFilename && (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)) { icons = [bundle objectForInfoDictionaryKey:@"CFBundleIcons~ipad"]; if (icons && [icons isKindOfClass:[NSDictionary class]]) { icons = [icons valueForKeyPath:@"CFBundlePrimaryIcon.CFBundleIconFiles"]; } NSString *iPadIconFilename = bit_validAppIconStringFromIcons(resourceBundle, icons); - if (iPadIconFilename && !iconFilename) { - iconFilename = iPadIconFilename; - } + iconFilename = iPadIconFilename; } if (!iconFilename) { diff --git a/docs/Changelog-template.md b/docs/Changelog-template.md index 5d7e1d27c3..1a2df57877 100644 --- a/docs/Changelog-template.md +++ b/docs/Changelog-template.md @@ -4,6 +4,7 @@ - [NEW] Added `preparedItemsForFeedbackManager:` method in `BITFeedbackManagerDelegate` to allow to provide items with every possible method of showing the feedback compose dialog. - [UPDATE] Deprecate `feedbackComposerPreparedItems` property in favor of the new delegate method. - [IMPROVEMENT] Prefix GZIP category on NSData to prevent symbol collisions +- [BUGFIX] Fix app icons with unusual filenames not showing in the in-app update prompt - [BUGFIX] Add minor UI bug when adding arrow annotation to feedback image ## Version 4.0.0-beta.1 From 5c2d2f332768ba7e712badd07353a6c2f71f9d38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Spie=C3=9F?= Date: Fri, 6 May 2016 18:11:59 +0200 Subject: [PATCH 5/7] Manually open simulator to prevent timeouts in CI runs --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 83a1953d9a..1414236e77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,6 +25,7 @@ before_install: - brew install carthage script: + - open -b com.apple.iphonesimulator - set -o pipefail - COMMAND="env NSUnbufferedIO=YES xcodebuild -project '$PROJECT' -scheme '$SCHEME' -sdk '$SDK' -configuration '$CONFIGURATION'" From 0f10557d1e8e7afe5dda463a33b3ceee03124db7 Mon Sep 17 00:00:00 2001 From: "Benjamin Scholtysik (Reimold)" Date: Fri, 2 Sep 2016 09:34:13 -0700 Subject: [PATCH 6/7] Fix paragraph about custom events and preseason --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ec977b4dab..b435738fb6 100644 --- a/README.md +++ b/README.md @@ -416,7 +416,7 @@ and set the delegate: HockeyApp automatically provides you with nice, intelligible, and informative metrics about how your app is used and by whom. - **Sessions**: A new session is tracked by the SDK whenever the containing app is restarted (this refers to a 'cold start', i.e. when the app has not already been in memory prior to being launched) or whenever it becomes active again after having been in the background for 20 seconds or more. - **Users**: The SDK anonymously tracks the users of your app by creating a random UUID that is then securely stored in the iOS keychain. Because this anonymous ID is stored in the keychain it persists across reinstallations. -- **Custom Events**: If you are part of [Preseason](https://www.hockeyapp.net/preseason/), you can now track Custom Events in your app, understand user actions and see the aggregates on the HockeyApp portal. +- **Custom Events**: With HockeySDK 4.1.0 you can now track Custom Events in your app, understand user actions and see the aggregates on the HockeyApp portal. Just in case you want to opt-out of the automatic collection of anonymous users and sessions statistics, there is a way to turn this functionality off at any time: From 5534d237b1c309e24271ae4b6330e1ff9d94564f Mon Sep 17 00:00:00 2001 From: "Benjamin Scholtysik (Reimold)" Date: Fri, 2 Sep 2016 10:20:34 -0700 Subject: [PATCH 7/7] Move entry in Changelog-template to correct release --- docs/Changelog-template.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/Changelog-template.md b/docs/Changelog-template.md index 9df609c56d..21e64be841 100644 --- a/docs/Changelog-template.md +++ b/docs/Changelog-template.md @@ -1,3 +1,6 @@ +## 4.1.1 +- [BUGFIX] Fix app icons with unusual filenames not showing in the in-app update prompt + ## 4.1.0 - Includes improvements from 4.0.2 release of the SDK. @@ -72,7 +75,6 @@ This SDK release explicitly includes the Application Support directory into back - [UPDATE] Our CrashOnly binary now includes User Metrics which enables crash free users statistics - [UPDATE] Deprecate `feedbackComposerPreparedItems` property in favor of the new delegate method. - [IMPROVEMENT] Prefix GZIP category on NSData to prevent symbol collisions -- [BUGFIX] Fix app icons with unusual filenames not showing in the in-app update prompt - [BUGFIX] Add minor UI bug when adding arrow annotation to feedback image ## Version 4.0.0-beta.1