[ios] Added download manager to iosapp
This commit is contained in:
committed by
Minh Nguyễn
parent
77657b3896
commit
081ee9fbef
9
platform/ios/app/MBXDownloadsTableViewController.h
Normal file
9
platform/ios/app/MBXDownloadsTableViewController.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@class MGLMapView;
|
||||
|
||||
@interface MBXDownloadsTableViewController : UITableViewController
|
||||
|
||||
@property (nonatomic, weak) MGLMapView *mapView;
|
||||
|
||||
@end
|
||||
175
platform/ios/app/MBXDownloadsTableViewController.m
Normal file
175
platform/ios/app/MBXDownloadsTableViewController.m
Normal file
@@ -0,0 +1,175 @@
|
||||
#import "MBXDownloadsTableViewController.h"
|
||||
|
||||
#import <Mapbox/Mapbox.h>
|
||||
|
||||
static NSString * const MBXDownloadContextNameKey = @"Name";
|
||||
|
||||
static NSString * const MBXDownloadsTableViewInactiveCellReuseIdentifier = @"Inactive";
|
||||
static NSString * const MBXDownloadsTableViewActiveCellReuseIdentifier = @"Active";
|
||||
|
||||
@implementation MGLDownloadable (MBXAdditions)
|
||||
|
||||
- (NSString *)name {
|
||||
NSDictionary *userInfo = [NSKeyedUnarchiver unarchiveObjectWithData:self.context];
|
||||
NSAssert([userInfo isKindOfClass:[NSDictionary class]], @"Context of downloadable isn’t a dictionary.");
|
||||
NSString *name = userInfo[MBXDownloadContextNameKey];
|
||||
NSAssert([name isKindOfClass:[NSString class]], @"Name of downloadable isn’t a string.");
|
||||
return name;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface MBXDownloadsTableViewController () <MGLDownloadableDelegate>
|
||||
|
||||
@property (nonatomic, strong) NS_MUTABLE_ARRAY_OF(MGLDownloadable *) *downloadables;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MBXDownloadsTableViewController {
|
||||
NSUInteger _untitledRegionCount;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
__weak MBXDownloadsTableViewController *weakSelf = self;
|
||||
[[MGLDownloadController sharedController] requestDownloadablesWithCompletionHandler:^(NS_ARRAY_OF(MGLDownloadable *) *downloadables, NSError *error) {
|
||||
MBXDownloadsTableViewController *strongSelf = weakSelf;
|
||||
strongSelf.downloadables = downloadables.mutableCopy;
|
||||
[strongSelf.tableView reloadData];
|
||||
|
||||
for (MGLDownloadable *downloadable in strongSelf.downloadables) {
|
||||
downloadable.delegate = strongSelf;
|
||||
[downloadable requestProgress];
|
||||
}
|
||||
|
||||
if (error) {
|
||||
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Can’t Find Downloads" message:@"Mapbox GL was unable to find the existing downloads." preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
|
||||
[self presentViewController:alertController animated:YES completion:^{
|
||||
[strongSelf dismissViewControllerAnimated:YES completion:nil];
|
||||
}];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (IBAction)addCurrentRegion:(id)sender {
|
||||
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Add Download" message:@"Choose a name for the download:" preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alertController addTextFieldWithConfigurationHandler:nil];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
|
||||
|
||||
UIAlertAction *downloadAction = [UIAlertAction actionWithTitle:@"Download" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
|
||||
MGLMapView *mapView = self.mapView;
|
||||
NSAssert(mapView, @"No map view to get the current region from.");
|
||||
|
||||
NSString *name = alertController.textFields.firstObject.text;
|
||||
if (!name.length) {
|
||||
name = [NSString stringWithFormat:@"Untitled %lu", (unsigned long)++_untitledRegionCount];
|
||||
}
|
||||
|
||||
MGLTilePyramidDownloadRegion *region = [[MGLTilePyramidDownloadRegion alloc] initWithStyleURL:mapView.styleURL bounds:mapView.visibleCoordinateBounds fromZoomLevel:mapView.zoomLevel toZoomLevel:mapView.maximumZoomLevel];
|
||||
NSData *context = [NSKeyedArchiver archivedDataWithRootObject:@{
|
||||
MBXDownloadContextNameKey: name,
|
||||
}];
|
||||
|
||||
__weak MBXDownloadsTableViewController *weakSelf = self;
|
||||
[[MGLDownloadController sharedController] addDownloadableForRegion:region withContext:context completionHandler:^(MGLDownloadable *downloadable, NSError *error) {
|
||||
MBXDownloadsTableViewController *strongSelf = weakSelf;
|
||||
if (error) {
|
||||
NSString *message = [NSString stringWithFormat:@"Mapbox GL was unable to add the download “%@”.", name];
|
||||
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Can’t Add Download" message:message preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
|
||||
[self presentViewController:alertController animated:YES completion:nil];
|
||||
} else {
|
||||
downloadable.delegate = strongSelf;
|
||||
[downloadable resume];
|
||||
|
||||
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:strongSelf.downloadables.count inSection:0];
|
||||
[strongSelf.downloadables addObject:downloadable];
|
||||
[strongSelf.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
}
|
||||
}];
|
||||
}];
|
||||
[alertController addAction:downloadAction];
|
||||
alertController.preferredAction = downloadAction;
|
||||
|
||||
[self presentViewController:alertController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
#pragma mark - Table view data source
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
return self.downloadables.count;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
MGLDownloadable *downloadable = self.downloadables[indexPath.row];
|
||||
|
||||
NSString *reuseIdentifier = downloadable.state == MGLDownloadableStateActive ? MBXDownloadsTableViewActiveCellReuseIdentifier : MBXDownloadsTableViewInactiveCellReuseIdentifier;
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier forIndexPath:indexPath];
|
||||
cell.textLabel.text = downloadable.name;
|
||||
MGLDownloadableProgress progress = downloadable.progress;
|
||||
NSString *completedString = [NSNumberFormatter localizedStringFromNumber:@(progress.countOfResourcesCompleted)
|
||||
numberStyle:NSNumberFormatterDecimalStyle];
|
||||
NSString *expectedString = [NSNumberFormatter localizedStringFromNumber:@(progress.countOfResourcesExpected)
|
||||
numberStyle:NSNumberFormatterDecimalStyle];
|
||||
NSString *byteCountString = [NSByteCountFormatter stringFromByteCount:progress.countOfBytesCompleted
|
||||
countStyle:NSByteCountFormatterCountStyleFile];
|
||||
NSString *statusString;
|
||||
switch (downloadable.state) {
|
||||
case MGLDownloadableStateInactive:
|
||||
case MGLDownloadableStateComplete:
|
||||
statusString = [NSString stringWithFormat:@"%@ of %@ resources (%@)",
|
||||
completedString, expectedString, byteCountString];
|
||||
break;
|
||||
|
||||
case MGLDownloadableStateActive:
|
||||
if (progress.countOfResourcesExpected) {
|
||||
completedString = [NSNumberFormatter localizedStringFromNumber:@(progress.countOfResourcesCompleted + 1)
|
||||
numberStyle:NSNumberFormatterDecimalStyle];
|
||||
}
|
||||
if (progress.maximumResourcesExpected > progress.countOfResourcesExpected) {
|
||||
expectedString = [@"at least " stringByAppendingString:expectedString];
|
||||
}
|
||||
statusString = [NSString stringWithFormat:@"Downloading %@ of %@ resources (%@ so far)…",
|
||||
completedString, expectedString, byteCountString];
|
||||
break;
|
||||
}
|
||||
cell.detailTextLabel.text = statusString;
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
if (editingStyle == UITableViewCellEditingStyleDelete) {
|
||||
MGLDownloadable *downloadable = self.downloadables[indexPath.row];
|
||||
__weak MBXDownloadsTableViewController *weakSelf = self;
|
||||
[[MGLDownloadController sharedController] removeDownloadable:downloadable withCompletionHandler:^(NSError *error) {
|
||||
MBXDownloadsTableViewController *strongSelf = weakSelf;
|
||||
[strongSelf.downloadables removeObjectAtIndex:indexPath.row];
|
||||
[strongSelf.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Downloadable delegate
|
||||
|
||||
- (void)downloadable:(MGLDownloadable *)downloadable progressDidChange:(MGLDownloadableProgress)progress {
|
||||
NSUInteger index = [self.downloadables indexOfObject:downloadable];
|
||||
if (index == NSNotFound) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
|
||||
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
|
||||
}
|
||||
|
||||
- (void)downloadable:(MGLDownloadable *)downloadable didReceiveError:(NSError *)error {
|
||||
NSLog(@"Downloadable “%@” received error: %@", downloadable.name, error.localizedFailureReason);
|
||||
}
|
||||
|
||||
- (void)downloadable:(MGLDownloadable *)downloadable didReceiveMaximumAllowedMapboxTiles:(uint64_t)maximumCount {
|
||||
NSLog(@"Downloadable “%@” reached limit of %llu tiles.", downloadable.name, maximumCount);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,5 +1,6 @@
|
||||
#import "MBXViewController.h"
|
||||
#import "MBXCustomCalloutView.h"
|
||||
#import "MBXDownloadsTableViewController.h"
|
||||
|
||||
#import <Mapbox/Mapbox.h>
|
||||
#import "../../../include/mbgl/util/default_styles.hpp"
|
||||
@@ -100,6 +101,13 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = {
|
||||
return UIInterfaceOrientationMaskAll;
|
||||
}
|
||||
|
||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(__unused id)sender {
|
||||
if ([segue.identifier isEqualToString:@"ShowDownloads"]) {
|
||||
MBXDownloadsTableViewController *controller = [segue destinationViewController];
|
||||
controller.mapView = self.mapView;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
- (IBAction)showSettings:(__unused id)sender
|
||||
@@ -109,33 +117,34 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = {
|
||||
delegate:self
|
||||
cancelButtonTitle:@"Cancel"
|
||||
destructiveButtonTitle:nil
|
||||
otherButtonTitles:@"Reset Position",
|
||||
((debugMask & MGLMapDebugTileBoundariesMask)
|
||||
? @"Hide Tile Boundaries"
|
||||
: @"Show Tile Boundaries"),
|
||||
((debugMask & MGLMapDebugTileInfoMask)
|
||||
? @"Hide Tile Info"
|
||||
: @"Show Tile Info"),
|
||||
((debugMask & MGLMapDebugTimestampsMask)
|
||||
? @"Hide Tile Timestamps"
|
||||
: @"Show Tile Timestamps"),
|
||||
((debugMask & MGLMapDebugCollisionBoxesMask)
|
||||
? @"Hide Collision Boxes"
|
||||
: @"Show Collision Boxes"),
|
||||
@"Empty Memory",
|
||||
@"Add 100 Points",
|
||||
@"Add 1,000 Points",
|
||||
@"Add 10,000 Points",
|
||||
@"Add Test Shapes",
|
||||
@"Start World Tour",
|
||||
@"Add Custom Callout Point",
|
||||
@"Remove Annotations",
|
||||
(_isShowingCustomStyleLayer
|
||||
? @"Hide Custom Style Layer"
|
||||
: @"Show Custom Style Layer"),
|
||||
@"Print Telemetry Logfile",
|
||||
@"Delete Telemetry Logfile",
|
||||
nil];
|
||||
otherButtonTitles:
|
||||
@"Reset Position",
|
||||
((debugMask & MGLMapDebugTileBoundariesMask)
|
||||
? @"Hide Tile Boundaries"
|
||||
: @"Show Tile Boundaries"),
|
||||
((debugMask & MGLMapDebugTileInfoMask)
|
||||
? @"Hide Tile Info"
|
||||
: @"Show Tile Info"),
|
||||
((debugMask & MGLMapDebugTimestampsMask)
|
||||
? @"Hide Tile Timestamps"
|
||||
: @"Show Tile Timestamps"),
|
||||
((debugMask & MGLMapDebugCollisionBoxesMask)
|
||||
? @"Hide Collision Boxes"
|
||||
: @"Show Collision Boxes"),
|
||||
@"Empty Memory",
|
||||
@"Add 100 Points",
|
||||
@"Add 1,000 Points",
|
||||
@"Add 10,000 Points",
|
||||
@"Add Test Shapes",
|
||||
@"Start World Tour",
|
||||
@"Add Custom Callout Point",
|
||||
@"Remove Annotations",
|
||||
(_isShowingCustomStyleLayer
|
||||
? @"Hide Custom Style Layer"
|
||||
: @"Show Custom Style Layer"),
|
||||
@"Print Telemetry Logfile",
|
||||
@"Delete Telemetry Logfile",
|
||||
nil];
|
||||
|
||||
[sheet showFromBarButtonItem:self.navigationItem.leftBarButtonItem animated:YES];
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10083"/>
|
||||
<capability name="Navigation items with more than one left or right bar item" minToolsVersion="7.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Map View Controller-->
|
||||
@@ -51,11 +52,18 @@
|
||||
<action selector="cycleStyles:" destination="WaX-pd-UZQ" eventType="touchUpInside" id="PnY-mb-J6m"/>
|
||||
</connections>
|
||||
</button>
|
||||
<barButtonItem key="rightBarButtonItem" image="TrackingLocationOffMask.png" id="CQ1-GP-M6x">
|
||||
<connections>
|
||||
<action selector="locateUser:" destination="WaX-pd-UZQ" id="XgF-DB-z3f"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
<rightBarButtonItems>
|
||||
<barButtonItem image="TrackingLocationOffMask.png" id="CQ1-GP-M6x">
|
||||
<connections>
|
||||
<action selector="locateUser:" destination="WaX-pd-UZQ" id="XgF-DB-z3f"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
<barButtonItem systemItem="organize" id="5IK-vz-jKQ">
|
||||
<connections>
|
||||
<segue destination="7q0-lI-zqb" kind="show" identifier="ShowDownloads" id="xjx-0t-0LD"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</rightBarButtonItems>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="mapView" destination="kNe-zV-9ha" id="VNR-WO-1q4"/>
|
||||
@@ -70,6 +78,81 @@
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1366" y="350"/>
|
||||
</scene>
|
||||
<!--Downloads-->
|
||||
<scene sceneID="xIg-PA-7r3">
|
||||
<objects>
|
||||
<tableViewController id="7q0-lI-zqb" customClass="MBXDownloadsTableViewController" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="eeN-6b-zqe">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="Inactive" editingAccessoryType="detailDisclosureButton" textLabel="JtH-Ce-MI5" detailTextLabel="tTJ-jv-U9v" style="IBUITableViewCellStyleSubtitle" id="fGu-Ys-Eh1">
|
||||
<rect key="frame" x="0.0" y="92" width="600" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="fGu-Ys-Eh1" id="sUf-bc-8xG">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="My Inactive Download" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="JtH-Ce-MI5">
|
||||
<rect key="frame" x="15" y="6" width="159" height="19.5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="456 resources (789 MB)" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="tTJ-jv-U9v">
|
||||
<rect key="frame" x="15" y="25.5" width="128" height="13.5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="Active" editingAccessoryType="detailDisclosureButton" textLabel="9ZK-gS-wJ4" detailTextLabel="0xK-p8-Mmh" style="IBUITableViewCellStyleSubtitle" id="mKB-tz-Zfl">
|
||||
<rect key="frame" x="0.0" y="136" width="600" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="mKB-tz-Zfl" id="nS3-aU-nBr">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="My Active Download" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="9ZK-gS-wJ4">
|
||||
<rect key="frame" x="15" y="6" width="147.5" height="19.5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Downloading 123 of 456 resources… (789 MB downloaded)" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="0xK-p8-Mmh">
|
||||
<rect key="frame" x="15" y="25.5" width="310.5" height="13.5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</prototypes>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="7q0-lI-zqb" id="oe8-d5-Rjo"/>
|
||||
<outlet property="delegate" destination="7q0-lI-zqb" id="D5X-oy-DSc"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="Downloads" id="UcK-PK-eQA">
|
||||
<barButtonItem key="rightBarButtonItem" systemItem="add" id="gCV-hl-Mzc">
|
||||
<connections>
|
||||
<action selector="addCurrentRegion:" destination="7q0-lI-zqb" id="G2O-3V-aEA"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Dga-Vh-IxZ" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="2075" y="350"/>
|
||||
</scene>
|
||||
<!--Navigation Controller-->
|
||||
<scene sceneID="LFg-oU-zTK">
|
||||
<objects>
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
'MBXAppDelegate.m',
|
||||
'MBXCustomCalloutView.h',
|
||||
'MBXCustomCalloutView.m',
|
||||
'MBXDownloadsTableViewController.h',
|
||||
'MBXDownloadsTableViewController.m',
|
||||
'MBXViewController.h',
|
||||
'MBXViewController.mm',
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user