HKWarnings v5.0.0
When I initially made HKWarnings universal and added an iPad interface, I based the interface on a MultipleDetailViews demo from Apple. That version is updated, I used the older code from 2010, so it’s 10 years old and built for iOS 3.2.
Architecturally, there’s a Master ViewController that displays multiple different Detail ViewControllers.
The Master ViewController is a TableView that’s usually hidden:
It’s used to choose one of many Detail VCs:
Anyway, this 10 year old code has survived 9 OS updates, but finally, on iOS 13, it no longer works. The code below that switches the Detail VC and hides the Master is called, but the UIPopoverController
is always nil
:
- (void)splitViewController:(UISplitViewController *)svc
willHideViewController:(UIViewController *)aViewController
withBarButtonItem:(UIBarButtonItem *)barButtonItem
forPopoverController:(UIPopoverController *)pc {
// Keep references to the popover controller and the popover button,
// and tell the detail view controller to show the button.
barButtonItem.title = NSLocalizedString(@"Menu", "Menu");
self.popoverController = pc;
self.rootPopoverButtonItem = barButtonItem;
UIViewController <SubstitutableDetailViewController> *detailViewController = [splitViewController.viewControllers objectAtIndex:1];
[detailViewController showRootPopoverButtonItem:rootPopoverButtonItem];
}
- (void)splitViewController:(UISplitViewController *)svc
willShowViewController:(UIViewController *)aViewController
invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem {
// Nil out references to the popover controller and the popover button,
// and tell the detail view controller to hide the button.
UIViewController <SubstitutableDetailViewController> *detailViewController = [splitViewController.viewControllers objectAtIndex:1];
[detailViewController invalidateRootPopoverButtonItem:rootPopoverButtonItem];
self.popoverController = nil;
self.rootPopoverButtonItem = nil;
}
Nothing I tried could make it work. There are not too many other people searching for an answer on Stackoverflow. I started a major rewrite based on the stock Xcode Master-Detail project:
But it’s all Storyboards, scenes and segues. I’m not a fan. I soon had a huge mess of a main storyboard. I prefer to do things programmatically, well, a mix of code and xibs.
Eventually I found MMDrawerController, it’s also fairly old code (targets iOS 7), but I quickly built a working prototype that worked on iOS 13.
It took a few days, but I have just released v5.0.0 of HKWarnings, using the new side drawer.
Code Changes
178 files were changed:
Lines changed:
james@Jamess-iMac: ~/Projects/iPhone Apps/HKWarnings on 5.0.1[!?$]
$ git log --numstat --pretty="%H" --author="James Stout" \
> b318bae1 bc535bb7 | grep -v Pods | grep -v Carthage \
> | awk 'NF==3 {plus+=$1; minus+=$2} END {printf("+%d, -%d\n", plus, minus)}'
+183978, -119453
+183978, -119453
BTW, that command takes a quite a while:
james@Jamess-iMac: ~/Projects/iPhone Apps/HKWarnings on 5.0.1[!?$]
$ time git log --numstat --pretty="%H" --author="James Stout" \
> b318bae1 bc535bb7 | grep -v Pods | grep -v Carthage \
> | awk 'NF==3 {plus+=$1; minus+=$2} END {printf("+%d, -%d\n", plus, minus)}'
+183978, -119453
real 0m40.285s
user 0m35.363s
sys 0m4.840s
Some Stats
cloc output, excluding Pods:
james@Jamess-iMac: ~/Projects/iPhone Apps/HKWarnings on 5.0.1[!?$]
$ cloc --ignored=ignored.txt \
> --exclude-dir=Pods,HKWeatherWarningsTabs.xcodeproj,HKWeatherWarningsTabs.xcworkspace \
> --exclude-ext=entitlements,plist,strings,xcodeproj \
> --report-file=cloc-report3.txt .
394 text files.
380 unique files.
Wrote ignored.txt
44 files ignored.
Wrote cloc-report3.txt
github.com/AlDanial/cloc v 1.84 T=0.40 s (873.2 files/s, 133349.8 lines/s)
--------------------------------------------------------------------------------
Language files blank comment code
--------------------------------------------------------------------------------
Objective C 91 11963 5279 20095
XML 41 105 5 3536
Bourne Shell 12 83 80 3522
JSON 99 1 0 3227
C/C++ Header 96 1073 1060 2157
Swift 2 108 40 448
HTML 1 19 0 420
Bourne Again Shell 7 44 11 146
Perl 1 21 121 30
YAML 1 0 0 7
--------------------------------------------------------------------------------
SUM: 351 13417 6596 33588
--------------------------------------------------------------------------------
Including Pods:
james@Jamess-iMac: ~/Projects/iPhone Apps/HKWarnings on 5.0.1[!?$]
$ cloc --ignored=ignored.txt \
> --exclude-dir=HKWeatherWarningsTabs.xcodeproj,HKWeatherWarningsTabs.xcworkspace \
> --exclude-ext=entitlements,plist,strings,xcodeproj \
--report-file=cloc-inc-pods-report3.txt .
1645 text files.
1101 unique files.
Wrote ignored.txt
697 files ignored.
Wrote cloc-inc-pods-report3.txt
github.com/AlDanial/cloc v 1.84 T=1.25 s (758.6 files/s, 101853.4 lines/s)
--------------------------------------------------------------------------------
Language files blank comment code
--------------------------------------------------------------------------------
Objective C 303 18922 11355 48001
C/C++ Header 443 5716 14128 9569
Bourne Shell 15 124 149 3804
XML 41 105 5 3536
Markdown 32 1410 0 3449
JSON 100 1 0 3255
C 3 379 261 1834
Swift 2 108 40 448
HTML 1 19 0 420
Bourne Again Shell 7 44 11 146
Perl 1 21 121 30
YAML 1 0 0 7
--------------------------------------------------------------------------------
SUM: 949 26849 26070 74499
--------------------------------------------------------------------------------
For reference, these are the Pods I use:
source 'https://github.com/CocoaPods/Specs.git'
source 'https://github.com/jamesstout/Specs.git'
platform :ios, '11.0'
target :HKWeatherWarningsTabs do
pod 'OneSignal'
pod 'Fabric'
pod 'Crashlytics', '~> 3.12'
pod 'MBProgressHUD', :git => 'https://github.com/jamesstout/MBProgressHUD.git', :branch => 'pre-iOS13'
pod 'StandardPaths'
pod 'SDWebImage', '~> 4.3'
pod 'SDWebImage/GIF'
pod 'SAMCategories'
pod 'TSMarkdownParser', '~> 2.1'
pod 'PureLayout'
pod 'FlatUIKit'
pod 'KVOController'
pod 'DTTJailbreakDetection'
pod 'OHAttributedStringAdditions'
pod 'JSQSystemSoundPlayer'
pod 'Google-Mobile-Ads-SDK'
pod 'NYTPhotoViewer', '~> 1.2.0'
pod 'DateTools'
pod 'HVTableView'
pod 'CocoaLumberjack', '~> 3.6.1'
pod 'CompressingAndUploadingLogFileManager'
pod 'GZIP', '~> 1.3.0'
pod 'MMDrawerController'
target :HKWarningsTests do
inherit! :search_paths
pod 'Expecta', '~> 1.0'
end
end
Significant Pods
- OneSignal - for push notifications.
- Fabric/Crashlytics - for crash reporting, moving to Firebase soon.
- MBProgressHUD - an iOS activity indicator view, but pointing to a branch on my fork, so it compiles on iOS 12.1.
- SDWebImage - an asynchronous image downloader with cache support.
- PureLayout - API for iOS & OS X Auto Layout. None of that IB rubbish.
- CocoaLumberjack - a fast & simple, yet powerful & flexible logging framework.
- CompressingAndUploadingLogFileManager - my, as yet unpublished1 library, that compresses log files and then uploads them to an HTTP server for examination, stats etc.
- GZIP - to unzip
.gz
files. To reduce package size I zip some text files. See below. - TSMarkdownParser - a markdown to NSAttributedString parser. I use it to display the acknowledgements Markdown created by the
pod install
command. Again, see below.
In my Podfile, I have a post_install
hook that does various things, including, copying the acknowledgements plist
to the Settings bundle, and the Markdown to a text file that I then compress.
require 'fileutils'
FileUtils.cp_r('Pods/Target Support Files/Pods-HKWeatherWarningsTabs/Pods-HKWeatherWarningsTabs-acknowledgements.plist', 'Settings.bundle/Acknowledgements.plist', :remove_destination => true)
FileUtils.cp_r('Pods/Target Support Files/Pods-HKWeatherWarningsTabs/Pods-HKWeatherWarningsTabs-acknowledgements.markdown', 'Acknowledgements.txt', :remove_destination => true)
require 'zlib'
zipped = "Acknowledgements.txt.gz"
Zlib::GzipWriter.open(zipped) do |gz|
gz.write IO.binread("Acknowledgements.txt")
end
In the app code to display the Markdown, I first unzip, then parse:
NSFileManager *fm = [NSFileManager defaultManager];
NSString *pathGZ = [fm pathForResource:@"Acknowledgements.txt.gz"];
if ([fm fileExistsAtPath:pathGZ]) {
NSData *zippedContent = [NSData dataWithContentsOfFile:pathGZ];
NSData *unZippedContent = nil;
NSString *content = nil;
if([zippedContent isGzippedData]){
DDLogDebug(@"Data is zipped");
unZippedContent = [zippedContent gunzippedData];
content = [[NSString alloc] initWithData:unZippedContent encoding:NSUTF8StringEncoding];
}
else{
DDLogError(@"Acknowledgements.txt.gz is not zipped");
content = @"ERROR";
}
DDLogDebug(@"content is %@", content);
self.parser = [TSMarkdownParser standardParser];
NSAttributedString *result = [self.parser attributedStringFromMarkdown:content];
_textView.attributedText = result;
}
Saves about 47kB2:
I do this so that I can display the acknowledgements in the app, and in the OS Settings app:
Anyway, here’s v5.0.0 (click through to view the video):