Skip to content
Snippets Groups Projects
Commit 654aa282 authored by Peter J. Keleher's avatar Peter J. Keleher
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
Showing
with 1488 additions and 0 deletions
.DS_Store 0 → 100644
File added
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
988DF87222491CDE005674C3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 988DF87122491CDE005674C3 /* AppDelegate.swift */; };
988DF87422491CDE005674C3 /* DocumentBrowserViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 988DF87322491CDE005674C3 /* DocumentBrowserViewController.swift */; };
988DF87622491CDE005674C3 /* CirclesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 988DF87522491CDE005674C3 /* CirclesViewController.swift */; };
988DF87822491CDE005674C3 /* CirclesDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 988DF87722491CDE005674C3 /* CirclesDocument.swift */; };
988DF87B22491CDE005674C3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 988DF87922491CDE005674C3 /* Main.storyboard */; };
988DF87D22491CDF005674C3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 988DF87C22491CDF005674C3 /* Assets.xcassets */; };
988DF88022491CDF005674C3 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 988DF87E22491CDF005674C3 /* LaunchScreen.storyboard */; };
988DF8882249239A005674C3 /* circles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 988DF8872249239A005674C3 /* circles.swift */; };
98C84FA422493A6000164E22 /* CircleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98C84FA322493A6000164E22 /* CircleView.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
988DF86E22491CDE005674C3 /* circles.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = circles.app; sourceTree = BUILT_PRODUCTS_DIR; };
988DF87122491CDE005674C3 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
988DF87322491CDE005674C3 /* DocumentBrowserViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentBrowserViewController.swift; sourceTree = "<group>"; };
988DF87522491CDE005674C3 /* CirclesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CirclesViewController.swift; sourceTree = "<group>"; };
988DF87722491CDE005674C3 /* CirclesDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CirclesDocument.swift; sourceTree = "<group>"; };
988DF87A22491CDE005674C3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
988DF87C22491CDF005674C3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
988DF87F22491CDF005674C3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
988DF88122491CDF005674C3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
988DF8872249239A005674C3 /* circles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = circles.swift; sourceTree = "<group>"; };
98C84FA322493A6000164E22 /* CircleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
988DF86B22491CDE005674C3 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
988DF86522491CDE005674C3 = {
isa = PBXGroup;
children = (
988DF87022491CDE005674C3 /* circles */,
988DF86F22491CDE005674C3 /* Products */,
);
sourceTree = "<group>";
};
988DF86F22491CDE005674C3 /* Products */ = {
isa = PBXGroup;
children = (
988DF86E22491CDE005674C3 /* circles.app */,
);
name = Products;
sourceTree = "<group>";
};
988DF87022491CDE005674C3 /* circles */ = {
isa = PBXGroup;
children = (
988DF87122491CDE005674C3 /* AppDelegate.swift */,
988DF87322491CDE005674C3 /* DocumentBrowserViewController.swift */,
988DF87522491CDE005674C3 /* CirclesViewController.swift */,
98C84FA322493A6000164E22 /* CircleView.swift */,
988DF87722491CDE005674C3 /* CirclesDocument.swift */,
988DF8872249239A005674C3 /* circles.swift */,
988DF87922491CDE005674C3 /* Main.storyboard */,
988DF87C22491CDF005674C3 /* Assets.xcassets */,
988DF87E22491CDF005674C3 /* LaunchScreen.storyboard */,
988DF88122491CDF005674C3 /* Info.plist */,
);
path = circles;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
988DF86D22491CDE005674C3 /* circles */ = {
isa = PBXNativeTarget;
buildConfigurationList = 988DF88422491CDF005674C3 /* Build configuration list for PBXNativeTarget "circles" */;
buildPhases = (
988DF86A22491CDE005674C3 /* Sources */,
988DF86B22491CDE005674C3 /* Frameworks */,
988DF86C22491CDE005674C3 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = circles;
productName = circles;
productReference = 988DF86E22491CDE005674C3 /* circles.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
988DF86622491CDE005674C3 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1010;
LastUpgradeCheck = 1010;
ORGANIZATIONNAME = PeteWorks;
TargetAttributes = {
988DF86D22491CDE005674C3 = {
CreatedOnToolsVersion = 10.1;
};
};
};
buildConfigurationList = 988DF86922491CDE005674C3 /* Build configuration list for PBXProject "circles" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 988DF86522491CDE005674C3;
productRefGroup = 988DF86F22491CDE005674C3 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
988DF86D22491CDE005674C3 /* circles */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
988DF86C22491CDE005674C3 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
988DF88022491CDF005674C3 /* LaunchScreen.storyboard in Resources */,
988DF87D22491CDF005674C3 /* Assets.xcassets in Resources */,
988DF87B22491CDE005674C3 /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
988DF86A22491CDE005674C3 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
988DF8882249239A005674C3 /* circles.swift in Sources */,
988DF87822491CDE005674C3 /* CirclesDocument.swift in Sources */,
988DF87622491CDE005674C3 /* CirclesViewController.swift in Sources */,
988DF87422491CDE005674C3 /* DocumentBrowserViewController.swift in Sources */,
98C84FA422493A6000164E22 /* CircleView.swift in Sources */,
988DF87222491CDE005674C3 /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
988DF87922491CDE005674C3 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
988DF87A22491CDE005674C3 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
988DF87E22491CDF005674C3 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
988DF87F22491CDF005674C3 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
988DF88222491CDF005674C3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
988DF88322491CDF005674C3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
988DF88522491CDF005674C3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 88APX46FR6;
INFOPLIST_FILE = circles/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = edu.umd.keleher.circles;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
988DF88622491CDF005674C3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 88APX46FR6;
INFOPLIST_FILE = circles/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = edu.umd.keleher.circles;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
988DF86922491CDE005674C3 /* Build configuration list for PBXProject "circles" */ = {
isa = XCConfigurationList;
buildConfigurations = (
988DF88222491CDF005674C3 /* Debug */,
988DF88322491CDF005674C3 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
988DF88422491CDF005674C3 /* Build configuration list for PBXNativeTarget "circles" */ = {
isa = XCConfigurationList;
buildConfigurations = (
988DF88522491CDF005674C3 /* Debug */,
988DF88622491CDF005674C3 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 988DF86622491CDE005674C3 /* Project object */;
}
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:circles.xcodeproj">
</FileRef>
</Workspace>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
uuid = "BF468F86-16DF-477B-9DEA-BBA50D239F8D"
type = "1"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "1837E095-7553-4B52-B621-AD39D07F6E4B"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "circles/DocumentBrowserViewController.swift"
timestampString = "575233516.666796"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "85"
endingLineNumber = "85"
landmarkName = "presentDocument(at:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "D9687F14-88BF-4126-A248-C0CC49CE56A7"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "circles/DocumentBrowserViewController.swift"
timestampString = "575233516.666886"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "58"
endingLineNumber = "58"
landmarkName = "documentBrowser(_:didRequestDocumentCreationWithHandler:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "77A1CE1D-AE4D-43FA-9651-C0C965E0B024"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "circles/circles.swift"
timestampString = "575233516.666944"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "32"
endingLineNumber = "32"
landmarkName = "init(json:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "21C6A6F5-8F29-4773-94C9-F06895B2629D"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "circles/CirclesDocument.swift"
timestampString = "575233516.666996"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "21"
endingLineNumber = "21"
landmarkName = "load(fromContents:ofType:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "DA134F96-CFA9-4AE4-92D0-D8BE4007E217"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "circles/CirclesDocument.swift"
timestampString = "575233516.667065"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "22"
endingLineNumber = "22"
landmarkName = "load(fromContents:ofType:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "9CD4712A-91A7-423B-926B-904BF7CD9927"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "circles/DocumentBrowserViewController.swift"
timestampString = "575233516.667136"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "42"
endingLineNumber = "42"
landmarkName = "viewDidLoad()"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "8D500AE0-31F4-4F73-BABE-525FFF88F2A4"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "circles/CircleView.swift"
timestampString = "575233516.667209"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "16"
endingLineNumber = "16"
landmarkName = "unknown"
landmarkType = "0">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "B8A492BB-1FBB-4C63-94CF-C92869998D1F"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "circles/CirclesViewController.swift"
timestampString = "575233516.667618"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "59"
endingLineNumber = "59"
landmarkName = "viewWillAppear(_:)"
landmarkType = "7">
<Locations>
<Location
uuid = "B8A492BB-1FBB-4C63-94CF-C92869998D1F - db34479b97b5d909"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "closure #1 (Swift.Bool) -&gt; () in circles.CirclesViewController.viewWillAppear(Swift.Bool) -&gt; ()"
moduleName = "circles"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/keleher/ios/ios436/workspace/projects/circles/circles/CirclesViewController.swift"
timestampString = "575230573.602545"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "52"
endingLineNumber = "52"
offsetFromSymbolStart = "1780">
</Location>
<Location
uuid = "B8A492BB-1FBB-4C63-94CF-C92869998D1F - 949ab308f43a145c"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "closure #1 () -&gt; () in closure #1 (Swift.Bool) -&gt; () in circles.CirclesViewController.viewWillAppear(Swift.Bool) -&gt; ()"
moduleName = "circles"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/keleher/ios/ios436/workspace/projects/circles/circles/CirclesViewController.swift"
timestampString = "575230573.604875"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "53"
endingLineNumber = "53"
offsetFromSymbolStart = "20">
</Location>
</Locations>
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "0BC07BE7-0A6E-4790-8B80-2445ACC89823"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "circles/CirclesDocument.swift"
timestampString = "575233516.667675"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "16"
endingLineNumber = "16"
landmarkName = "contents(forType:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "BA637846-5D76-49D5-A8FA-A58425F9D986"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "circles/DocumentBrowserViewController.swift"
timestampString = "575233516.667726"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "87"
endingLineNumber = "87"
landmarkName = "presentDocument(at:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "8AB6C7C2-A1D4-450A-99D1-63E9D169EECF"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "circles/DocumentBrowserViewController.swift"
timestampString = "575233516.667767"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "89"
endingLineNumber = "89"
landmarkName = "presentDocument(at:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "86594E93-9D06-4547-A3B7-97E1C758D41D"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "circles/CirclesDocument.swift"
timestampString = "575233516.667804"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "20"
endingLineNumber = "20"
landmarkName = "load(fromContents:ofType:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "85E6519F-D5A9-4B73-8CDF-329BF4DBC17D"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "circles/CirclesViewController.swift"
timestampString = "575233516.667855"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "42"
endingLineNumber = "42"
landmarkName = "viewWillAppear(_:)"
landmarkType = "7">
<Locations>
<Location
uuid = "85E6519F-D5A9-4B73-8CDF-329BF4DBC17D - 675b3b575299706a"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "circles.CirclesViewController.viewWillAppear(Swift.Bool) -&gt; ()"
moduleName = "circles"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/keleher/ios/ios436/workspace/projects/circles/circles/CirclesViewController.swift"
timestampString = "575230573.619588"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "34"
endingLineNumber = "34"
offsetFromSymbolStart = "163">
</Location>
<Location
uuid = "85E6519F-D5A9-4B73-8CDF-329BF4DBC17D - db34479b97b5d909"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "closure #1 (Swift.Bool) -&gt; () in circles.CirclesViewController.viewWillAppear(Swift.Bool) -&gt; ()"
moduleName = "circles"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/keleher/ios/ios436/workspace/projects/circles/circles/CirclesViewController.swift"
timestampString = "575230573.620918"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "35"
endingLineNumber = "35"
offsetFromSymbolStart = "44">
</Location>
</Locations>
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "A1462011-F331-4B19-92B0-C9D0A81C555C"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "circles/CirclesViewController.swift"
timestampString = "575233516.667902"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "19"
endingLineNumber = "19"
landmarkName = "doTap(recog:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "E1CEF454-9927-4A26-890E-9E00E322A356"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "circles/CirclesViewController.swift"
timestampString = "575233516.667941"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "26"
endingLineNumber = "26"
landmarkName = "doTapExit(recog:)"
landmarkType = "7">
<Locations>
<Location
uuid = "E1CEF454-9927-4A26-890E-9E00E322A356 - 78908bec692fcee"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "circles.CirclesViewController.doTapExit(recog: __C.UITapGestureRecognizer) -&gt; ()"
moduleName = "circles"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/keleher/ios/ios436/workspace/projects/circles/circles/CirclesViewController.swift"
timestampString = "575230934.964911"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "26"
endingLineNumber = "26"
offsetFromSymbolStart = "32">
</Location>
<Location
uuid = "E1CEF454-9927-4A26-890E-9E00E322A356 - ce1ca8bd21b906dc"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "closure #1 () -&gt; () in circles.CirclesViewController.doTapExit(recog: __C.UITapGestureRecognizer) -&gt; ()"
moduleName = "circles"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/keleher/ios/ios436/workspace/projects/circles/circles/CirclesViewController.swift"
timestampString = "575230934.966422"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "27"
endingLineNumber = "27"
offsetFromSymbolStart = "29">
</Location>
</Locations>
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "CAAFE5A5-41A3-44FE-8A6E-EA66D035ADB1"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "circles/CirclesViewController.swift"
timestampString = "575233516.667998"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "32"
endingLineNumber = "32"
landmarkName = "gestureRecognizer(_:shouldRequireFailureOf:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "59AAC780-5D05-4AD0-8004-D5F954441900"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "circles/DocumentBrowserViewController.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "69"
endingLineNumber = "69"
landmarkName = "documentBrowser(_:didPickDocumentsAt:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>circles.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
</dict>
</plist>
//
// AppDelegate.swift
// circles
//
// Created by Pete Keleher on 3/25/19.
// Copyright © 2019 PeteWorks. All rights reserved.
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
func application(_ app: UIApplication, open inputURL: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
// Ensure the URL is a file URL
guard inputURL.isFileURL else { return false }
// Reveal / import the document at the URL
guard let documentBrowserViewController = window?.rootViewController as? DocumentBrowserViewController else { return false }
documentBrowserViewController.revealDocument(at: inputURL, importIfNeeded: true) { (revealedDocumentURL, error) in
if let error = error {
// Handle the error appropriately
print("Failed to reveal the document at URL \(inputURL) with error: '\(error)'")
return
}
// Present the Document View Controller for the revealed URL
documentBrowserViewController.presentDocument(at: revealedDocumentURL!)
}
return true
}
}
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Document Browser View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="DocumentBrowserViewController" customModule="circles" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="0fo-ii-Aj5"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="26" y="654"/>
</scene>
<!--Circles View Controller-->
<scene sceneID="UGw-BM-Uqg">
<objects>
<viewController storyboardIdentifier="CirclesViewController" id="3iE-ED-OZ3" customClass="CirclesViewController" customModule="circles" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="6nl-7g-gYK" customClass="CircleView" customModule="circles" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<viewLayoutGuide key="safeArea" id="Em0-4J-Gf4"/>
</view>
<connections>
<outlet property="circleView" destination="6nl-7g-gYK" id="i9D-dt-b2G"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="meG-mw-ddx" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-506" y="280"/>
</scene>
<!--View Controller-->
<scene sceneID="dkP-xk-x6W">
<objects>
<viewController id="M2k-L8-Olo" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="SIE-Uh-Zny">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" spacing="24" translatesAutoresizingMaskIntoConstraints="NO" id="2l7-xg-u1v">
<rect key="frame" x="80" y="293.5" width="215" height="80.5"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" alignment="firstBaseline" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="Jzy-az-Q3G">
<rect key="frame" x="0.0" y="0.0" width="215" height="20.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="File Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="TDw-Fo-hfZ">
<rect key="frame" x="0.0" y="0.0" width="76" height="20.5"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Document Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="s46-Uc-0IM">
<rect key="frame" x="86" y="0.0" width="129" height="20.5"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="WAb-IC-g0u">
<rect key="frame" x="84" y="44.5" width="47" height="36"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleTitle2"/>
<state key="normal" title="Done"/>
<connections>
<action selector="dismissDocumentViewController" destination="M2k-L8-Olo" eventType="touchUpInside" id="Hqu-HM-7pb"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="2l7-xg-u1v" firstAttribute="centerX" secondItem="SIE-Uh-Zny" secondAttribute="centerX" id="UUS-kO-C91"/>
<constraint firstItem="2l7-xg-u1v" firstAttribute="centerY" secondItem="SIE-Uh-Zny" secondAttribute="centerY" id="yEe-m6-dL4"/>
</constraints>
<viewLayoutGuide key="safeArea" id="BoZ-jc-2Y8"/>
</view>
<connections>
<outlet property="documentNameLabel" destination="s46-Uc-0IM" id="S9N-4c-eHT"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Rl9-ES-qQn" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="759" y="654"/>
</scene>
</scenes>
</document>
//
// circleView.swift
// circles
//
// Created by Pete Keleher on 3/25/19.
// Copyright © 2019 PeteWorks. All rights reserved.
//
import UIKit
class CircleView: UIView {
var circleContainer: CircleContainer?
override func draw(_ rect: CGRect) {
if let container = circleContainer {
let path = UIBezierPath()
// container.circles.append(Circle(c: CGPoint(x: 100, y: 100), r: 45))
for c in container.circles {
path.append(UIBezierPath(arcCenter: c.center, radius: c.radius, startAngle: 0, endAngle: CGFloat.pi*2, clockwise: true))
}
UIColor.green.setStroke()
path.lineWidth = 2
path.stroke()
}
}
}
//
// circleView.swift
// circles
//
// Created by Pete Keleher on 3/25/19.
// Copyright © 2019 PeteWorks. All rights reserved.
//
import UIKit
class CircleView: UIView {
override func draw(_ rect: CGRect) {
if var container = self.circlesDocument?.container {
let path = UIBezierPath()
container.circles.append(Circle(c: CGPoint(x: 100, y: 100), r: 45))
for c in container.circles {
path.append(UIBezierPath(arcCenter: c.center, radius: c.radius, startAngle: 0, endAngle: CGFloat.pi*2, clockwise: true))
}
let layer = CAShapeLayer()
layer.path = path.cgPath
layer.strokeColor = UIColor.green.cgColor
layer.lineWidth = 2
self.view.layer.addSublayer(layer)
}
}
}
//
// Document.swift
// circles
//
// Created by Pete Keleher on 3/25/19.
// Copyright © 2019 PeteWorks. All rights reserved.
//
import UIKit
class CirclesDocument: UIDocument {
var container: CircleContainer?
override func contents(forType typeName: String) throws -> Any {
// Encode your document with an instance of NSData or NSFileWrapper
return container?.json ?? Data()
}
override func load(fromContents contents: Any, ofType typeName: String?) throws {
if let data = contents as? Data {
container = CircleContainer(json: data)
}
}
}
//
// DocumentViewController.swift
// circles
//
// Created by Pete Keleher on 3/25/19.
// Copyright © 2019 PeteWorks. All rights reserved.
//
import UIKit
class CirclesViewController: UIViewController, UIGestureRecognizerDelegate {
@IBOutlet var circleView: CircleView!
var circlesDocument: CirclesDocument?
@objc func doTap(recog: UITapGestureRecognizer) {
let loc = recog.location(in: view)
circlesDocument?.container?.circles.append(Circle(c: loc, r: 100))
circleView.setNeedsDisplay()
circlesDocument?.updateChangeCount(.done)
}
@objc func doTapExit(recog: UITapGestureRecognizer) {
dismiss(animated: true) {
self.circlesDocument?.close(completionHandler: nil)
}
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return ((gestureRecognizer == self.tapRecog) && (otherGestureRecognizer == self.doubleTapRecog))
}
var tapRecog: UITapGestureRecognizer!
var doubleTapRecog: UITapGestureRecognizer!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Access the document
circlesDocument?.open(completionHandler: { (success) in
if success {
if let container = self.circlesDocument?.container {
self.circleView.circleContainer = container
self.circleView.setNeedsDisplay()
self.tapRecog = UITapGestureRecognizer(target: self, action: #selector(self.doTap))
self.tapRecog.numberOfTapsRequired = 1
self.circleView.addGestureRecognizer(self.tapRecog)
self.tapRecog.delegate = self
self.doubleTapRecog = UITapGestureRecognizer(target: self, action: #selector(self.doTapExit))
self.doubleTapRecog.numberOfTapsRequired = 2
self.view.addGestureRecognizer(self.doubleTapRecog)
}
} else {
self.presentWarningWith(title: "Error", message: "Document can't be viewed.") {
self.dismiss(animated: true)
}
}
})
}
@IBAction func dismissDocumentViewController() {
dismiss(animated: true) {
self.circlesDocument?.close(completionHandler: nil)
}
}
}
extension UIViewController {
// MARK: - Factories
/// Returns an alert controller with the passed title and message.
func makeAlertWith(title: String, message: String) -> UIAlertController {
return UIAlertController(title: title, message: message, preferredStyle: .alert)
}
// MARK: - Imperatives
/// Presents a warning alert with the provided title and message.
func presentWarningWith(title: String, message: String, handler: Optional<() -> ()> = nil) {
let alert = makeAlertWith(title: title, message: message)
_ = alert.addActionWith(title: "Ok", style: .default)
present(alert, animated: true, completion: handler)
}
}
extension UIAlertController {
// MARK: - Imperatives
/// Adds a new alert action to the alert controller.
func addActionWith(title: String, style: UIAlertAction.Style = .default, handler: Optional<(UIAlertAction) -> Swift.Void> = nil) -> UIAlertAction {
let action = UIAlertAction(title: title, style: style, handler: handler)
addAction(action)
return action
}
}
//
// DocumentBrowserViewController.swift
// circles
//
// Created by Pete Keleher on 3/25/19.
// Copyright © 2019 PeteWorks. All rights reserved.
//
import UIKit
class DocumentBrowserViewController: UIDocumentBrowserViewController, UIDocumentBrowserViewControllerDelegate {
var templateURL: URL?
override func viewDidLoad() {
super.viewDidLoad()
delegate = self
allowsDocumentCreation = true
allowsPickingMultipleItems = false
// Update the style of the UIDocumentBrowserViewController
// browserUserInterfaceStyle = .dark
// view.tintColor = .white
// Specify the allowed content types of your application via the Info.plist.
// Do any additional setup after loading the view, typically from a nib.
// Creates the template file:
let fileManager = FileManager.default
templateURL = try? fileManager.url(
for: .applicationSupportDirectory,
in: .userDomainMask,
appropriateFor: nil,
create: true
).appendingPathComponent("untitled.circles")
if let templateURL = templateURL {
allowsDocumentCreation = fileManager.createFile(atPath: templateURL.path, contents: Data())
// Writes an empty image gallery into the template file:
let emptyCircles = CircleContainer(name: "untitled")
_ = try? JSONEncoder().encode(emptyCircles).write(to: templateURL)
}
}
// MARK: UIDocumentBrowserViewControllerDelegate
func documentBrowser(_ controller: UIDocumentBrowserViewController, didRequestDocumentCreationWithHandler importHandler: @escaping (URL?, UIDocumentBrowserViewController.ImportMode) -> Void) {
if templateURL != nil {
importHandler(templateURL, .copy)
} else {
importHandler(nil, .none)
}
}
func documentBrowser(_ controller: UIDocumentBrowserViewController, didPickDocumentsAt documentURLs: [URL]) {
guard let sourceURL = documentURLs.first else { return }
// Present the Document View Controller for the first document that was picked.
// If you support picking multiple items, make sure you handle them all.
presentDocument(at: sourceURL)
}
func documentBrowser(_ controller: UIDocumentBrowserViewController, didImportDocumentAt sourceURL: URL, toDestinationURL destinationURL: URL) {
// Present the Document View Controller for the new newly created document
presentDocument(at: destinationURL)
}
func documentBrowser(_ controller: UIDocumentBrowserViewController, failedToImportDocumentAt documentURL: URL, error: Error?) {
// Make sure to handle the failed import appropriately, e.g., by presenting an error message to the user.
}
// MARK: Document Presentation
func presentDocument(at documentURL: URL) {
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
let documentViewController = storyBoard.instantiateViewController(withIdentifier: "CirclesViewController") as! CirclesViewController
documentViewController.circlesDocument = CirclesDocument(fileURL: documentURL)
present(documentViewController, animated: true, completion: nil)
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeIconFiles</key>
<array/>
<key>CFBundleTypeName</key>
<string>circles</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>edu.umd.keleher.circles</string>
</array>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportsDocumentBrowser</key>
<true/>
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>circles</string>
<key>UTTypeIconFiles</key>
<array/>
<key>UTTypeIdentifier</key>
<string>edu.umd.keleher.circles</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<string>circles</string>
</dict>
</dict>
</array>
</dict>
</plist>
//
// circles.swift
// circles
//
// Created by Pete Keleher on 3/25/19.
// Copyright © 2019 PeteWorks. All rights reserved.
//
import Foundation
import UIKit
struct Circle : Codable {
var center : CGPoint
var radius : CGFloat
init(c: CGPoint, r: CGFloat) {
center = c
radius = r
}
}
class CircleContainer : Codable {
var circles: [Circle] = []
var name: String
init(name: String) {
self.name = name
}
init?(json: Data) {
if let decodedSelf = try? JSONDecoder().decode(CircleContainer.self, from: json) {
self.name = decodedSelf.name
self.circles = decodedSelf.circles
} else {
return nil
}
}
var json: Data? {
return try? JSONEncoder().encode(self)
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment