Add projects

This commit is contained in:
Ivan Vorobei
2019-06-07 08:56:26 +03:00
parent f1382c2bca
commit 5b758db8cd
117 changed files with 5413 additions and 0 deletions

68
Examples/Calculator/.gitignore vendored Executable file
View File

@@ -0,0 +1,68 @@
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## Build generated
build/
DerivedData/
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/
## Other
*.moved-aside
*.xccheckout
*.xcscmblueprint
## Obj-C/Swift specific
*.hmap
*.ipa
*.dSYM.zip
*.dSYM
## Playgrounds
timeline.xctimeline
playground.xcworkspace
# Swift Package Manager
#
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
# Package.pins
# Package.resolved
.build/
# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts
Carthage/Build
# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output

View File

@@ -0,0 +1,349 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
FB5DD72922A8D8D000642035 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB5DD72822A8D8D000642035 /* AppDelegate.swift */; };
FB5DD72B22A8D8D000642035 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB5DD72A22A8D8D000642035 /* SceneDelegate.swift */; };
FB5DD72D22A8D8D000642035 /* Calculator.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB5DD72C22A8D8D000642035 /* Calculator.swift */; };
FB5DD72F22A8D8D100642035 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FB5DD72E22A8D8D100642035 /* Assets.xcassets */; };
FB5DD73222A8D8D100642035 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FB5DD73122A8D8D100642035 /* Preview Assets.xcassets */; };
FB5DD73522A8D8D100642035 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB5DD73322A8D8D100642035 /* LaunchScreen.storyboard */; };
FB5DD73D22A8D9C800642035 /* CalculatorBrain.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB5DD73C22A8D9C800642035 /* CalculatorBrain.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
FB5DD72522A8D8D000642035 /* Calculator.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Calculator.app; sourceTree = BUILT_PRODUCTS_DIR; };
FB5DD72822A8D8D000642035 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
FB5DD72A22A8D8D000642035 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
FB5DD72C22A8D8D000642035 /* Calculator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Calculator.swift; sourceTree = "<group>"; };
FB5DD72E22A8D8D100642035 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
FB5DD73122A8D8D100642035 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
FB5DD73422A8D8D100642035 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
FB5DD73622A8D8D100642035 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
FB5DD73C22A8D9C800642035 /* CalculatorBrain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalculatorBrain.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
FB5DD72222A8D8D000642035 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
FB5DD71C22A8D8D000642035 = {
isa = PBXGroup;
children = (
FB5DD72722A8D8D000642035 /* Calculator */,
FB5DD72622A8D8D000642035 /* Products */,
);
sourceTree = "<group>";
};
FB5DD72622A8D8D000642035 /* Products */ = {
isa = PBXGroup;
children = (
FB5DD72522A8D8D000642035 /* Calculator.app */,
);
name = Products;
sourceTree = "<group>";
};
FB5DD72722A8D8D000642035 /* Calculator */ = {
isa = PBXGroup;
children = (
FB5DD72822A8D8D000642035 /* AppDelegate.swift */,
FB5DD72A22A8D8D000642035 /* SceneDelegate.swift */,
FB5DD72C22A8D8D000642035 /* Calculator.swift */,
FB5DD73C22A8D9C800642035 /* CalculatorBrain.swift */,
FB5DD72E22A8D8D100642035 /* Assets.xcassets */,
FB5DD73322A8D8D100642035 /* LaunchScreen.storyboard */,
FB5DD73622A8D8D100642035 /* Info.plist */,
FB5DD73022A8D8D100642035 /* Preview Content */,
);
path = Calculator;
sourceTree = "<group>";
};
FB5DD73022A8D8D100642035 /* Preview Content */ = {
isa = PBXGroup;
children = (
FB5DD73122A8D8D100642035 /* Preview Assets.xcassets */,
);
path = "Preview Content";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
FB5DD72422A8D8D000642035 /* Calculator */ = {
isa = PBXNativeTarget;
buildConfigurationList = FB5DD73922A8D8D100642035 /* Build configuration list for PBXNativeTarget "Calculator" */;
buildPhases = (
FB5DD72122A8D8D000642035 /* Sources */,
FB5DD72222A8D8D000642035 /* Frameworks */,
FB5DD72322A8D8D000642035 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = Calculator;
productName = Calculator;
productReference = FB5DD72522A8D8D000642035 /* Calculator.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
FB5DD71D22A8D8D000642035 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1100;
LastUpgradeCheck = 1100;
ORGANIZATIONNAME = NSHotchner;
TargetAttributes = {
FB5DD72422A8D8D000642035 = {
CreatedOnToolsVersion = 11.0;
};
};
};
buildConfigurationList = FB5DD72022A8D8D000642035 /* Build configuration list for PBXProject "Calculator" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = FB5DD71C22A8D8D000642035;
productRefGroup = FB5DD72622A8D8D000642035 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
FB5DD72422A8D8D000642035 /* Calculator */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
FB5DD72322A8D8D000642035 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
FB5DD73522A8D8D100642035 /* LaunchScreen.storyboard in Resources */,
FB5DD73222A8D8D100642035 /* Preview Assets.xcassets in Resources */,
FB5DD72F22A8D8D100642035 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
FB5DD72122A8D8D000642035 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
FB5DD72922A8D8D000642035 /* AppDelegate.swift in Sources */,
FB5DD72B22A8D8D000642035 /* SceneDelegate.swift in Sources */,
FB5DD73D22A8D9C800642035 /* CalculatorBrain.swift in Sources */,
FB5DD72D22A8D8D000642035 /* Calculator.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
FB5DD73322A8D8D100642035 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
FB5DD73422A8D8D100642035 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
FB5DD73722A8D8D100642035 /* 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;
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 = 13.0;
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;
};
FB5DD73822A8D8D100642035 /* 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;
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 = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
FB5DD73A22A8D8D100642035 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "Calculator/Preview\\ Content";
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = Calculator/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = hotchner.tk.Calculator;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
FB5DD73B22A8D8D100642035 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "Calculator/Preview\\ Content";
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = Calculator/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = hotchner.tk.Calculator;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
FB5DD72022A8D8D000642035 /* Build configuration list for PBXProject "Calculator" */ = {
isa = XCConfigurationList;
buildConfigurations = (
FB5DD73722A8D8D100642035 /* Debug */,
FB5DD73822A8D8D100642035 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
FB5DD73922A8D8D100642035 /* Build configuration list for PBXNativeTarget "Calculator" */ = {
isa = XCConfigurationList;
buildConfigurations = (
FB5DD73A22A8D8D100642035 /* Debug */,
FB5DD73B22A8D8D100642035 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = FB5DD71D22A8D8D000642035 /* Project object */;
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Calculator.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -0,0 +1,8 @@
<?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>

View File

@@ -0,0 +1,41 @@
//
// AppDelegate.swift
// Calculator
//
// Created by on 2019/6/6.
// Copyright © 2019 NSHotchner. All rights reserved.
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}

View File

@@ -0,0 +1,98 @@
{
"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"
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -0,0 +1,25 @@
<?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" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<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>

View File

@@ -0,0 +1,96 @@
//
// Calculator.swift
// Calculator
//
// Created by on 2019/6/6.
// Copyright © 2019 NSHotchner. All rights reserved.
//
import SwiftUI
struct Calculator: View {
@State private var userIsInTheMiddleOfTyping = false
@State private var display = "0"
@State private var brain = CalculatorBrain()
let data = [["+", "", "÷", "×"],
["π", "7", "8", "9"],
["", "4", "5", "6"],
["cos", "1", "2", "3"],
["±", ".", "0", "="]]
var body: some View {
let margin: CGFloat = 10
return VStack(alignment: .center) {
HStack {
Spacer()
Text(display)
.foregroundColor(Color(red: 231 / 255.0, green: 76 / 255.0, blue: 60 / 255.0))
.font(.largeTitle)
.frame(height: 50)
}
.padding(margin)
VStack(alignment: .center, spacing: margin) {
ForEach(data.identified(by: \.description)) { items in
HStack(alignment: .center, spacing: margin) {
ForEach(items.identified(by: \.description)) { item in
Text(item)
.font(.title)
.bold()
.color(Color.blue)
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
.background(Color(red: 234 / 255.0, green: 240 / 255.0, blue: 241 / 255.0))
.tapAction {
self.touchAction(item)
}
}
}
}
}
.padding(EdgeInsets(top: 0, leading: margin, bottom: 0, trailing: margin))
}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
}
private func touchAction(_ symbol: String) {
if Int(symbol) != nil || symbol == "." {
touchDigit(symbol)
} else {
performOperation(symbol)
}
}
private func touchDigit(_ digit: String) {
print(#function)
if userIsInTheMiddleOfTyping {
display += digit
} else {
display = digit
userIsInTheMiddleOfTyping = true
}
}
private func performOperation(_ symbol: String) {
print(#function)
if userIsInTheMiddleOfTyping {
brain.setOperand(Double(display)!)
userIsInTheMiddleOfTyping = false
}
brain.performOperation(symbol)
if let result = brain.result {
display = String(result)
}
}
}
#if DEBUG
struct Calculator_Previews : PreviewProvider {
static var previews: some View {
Calculator()
}
}
#endif

View File

@@ -0,0 +1,96 @@
//
// CalculatorBrain.swift
// Calculator
//
// Created by on 2019/6/6.
// Copyright © 2019 NSHotchner. All rights reserved.
// from class
import Foundation
struct CalculatorBrain {
// optional on initialization = not set
private var accumulator: Double?
// private enum specifying operation types
// with an associated value
private enum Operation {
case constant(Double)
case unary((Double) -> Double)
case binary((Double,Double) -> Double)
case equals
}
// private extensible dictionary of operations with closures
private var operations: Dictionary<String,Operation> = [
"π" : Operation.constant(Double.pi),
"e" : Operation.constant(M_E),
"" : Operation.unary(sqrt),
"cos" : Operation.unary(cos),
"±" : Operation.unary({ -$0 }),
"×" : Operation.binary({ $0 * $1 }),
"÷" : Operation.binary({ $0 / $1 }),
"+" : Operation.binary({ $0 + $1 }),
"" : Operation.binary({ $0 - $1 }),
"=" : Operation.equals
]
mutating func performOperation(_ symbol: String) {
if let operation = operations[symbol] {
switch operation {
case .constant(let value):
accumulator = value
case .unary(let f):
if accumulator != nil {
accumulator = f(accumulator!)
}
case .binary(let f):
if accumulator != nil {
pendingBinaryOperation = PendingBinaryOperation(function: f, firstOperand: accumulator!)
accumulator = nil
}
case .equals:
performPendingBinaryOperation()
}
} else {
print("wrong operation symbol")
}
}
// Private mutating func for performing pending binary operations
mutating func performPendingBinaryOperation() {
if pendingBinaryOperation != nil && accumulator != nil {
accumulator = pendingBinaryOperation!.perform(with: accumulator!)
pendingBinaryOperation = nil
}
}
// Private optional Pending Binary Operation
private var pendingBinaryOperation: PendingBinaryOperation?
// embedded private struct to support binary operations
// with a constant function and pending first operand
// doesn't need mutating since its just returning a value
private struct PendingBinaryOperation {
let function: (Double, Double) -> Double
let firstOperand: Double
func perform(with secondOperand: Double) -> Double {
return function(firstOperand, secondOperand)
}
}
// mark method as mutating in order to assign to property
mutating func setOperand(_ operand: Double) {
accumulator = operand
}
// return an optional since the accumulator can be not set
var result: Double? {
get {
return accumulator
}
}
}

View File

@@ -0,0 +1,62 @@
<?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>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>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
</dict>
</array>
</dict>
</dict>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</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>
</dict>
</plist>

View File

@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -0,0 +1,59 @@
//
// SceneDelegate.swift
// Calculator
//
// Created by on 2019/6/6.
// Copyright © 2019 NSHotchner. All rights reserved.
//
import UIKit
import SwiftUI
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
// Use a UIHostingController as window root view controller
let window = UIWindow(frame: UIScreen.main.bounds)
window.rootViewController = UIHostingController(rootView: Calculator())
self.window = window
window.makeKeyAndVisible()
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
}
}

21
Examples/Calculator/LICENSE Executable file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 hotchner
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

11
Examples/Calculator/README.md Executable file
View File

@@ -0,0 +1,11 @@
# SwiftUICalculator
SwiftUI 实现的计算器
<img width="25%" height="25%" src="screenShots/1.png"/> <img width="50%" height="50%" src="screenShots/2.png"/>
## Requirements
* Xcode 11 Beta
* Swift 5.1
* iOS 13.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

View File

@@ -0,0 +1,386 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
C313C0B822A6FBAC00FF2AFB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C313C0B722A6FBAC00FF2AFB /* AppDelegate.swift */; };
C313C0BA22A6FBAC00FF2AFB /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C313C0B922A6FBAC00FF2AFB /* SceneDelegate.swift */; };
C313C0BD22A6FBAC00FF2AFB /* Instagram_SWUI.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = C313C0BB22A6FBAC00FF2AFB /* Instagram_SWUI.xcdatamodeld */; };
C313C0BF22A6FBAC00FF2AFB /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C313C0BE22A6FBAC00FF2AFB /* ContentView.swift */; };
C313C0C122A6FBAE00FF2AFB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C313C0C022A6FBAE00FF2AFB /* Assets.xcassets */; };
C313C0C422A6FBAE00FF2AFB /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C313C0C322A6FBAE00FF2AFB /* Preview Assets.xcassets */; };
C313C0C722A6FBAE00FF2AFB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C313C0C522A6FBAE00FF2AFB /* LaunchScreen.storyboard */; };
C313C0F422A727EE00FF2AFB /* InstaPhoto.swift in Sources */ = {isa = PBXBuildFile; fileRef = C313C0F322A727EE00FF2AFB /* InstaPhoto.swift */; };
C313C10222A778D100FF2AFB /* PhotoLibrary.swift in Sources */ = {isa = PBXBuildFile; fileRef = C313C10122A778D100FF2AFB /* PhotoLibrary.swift */; };
C313C10822A8301D00FF2AFB /* CameraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C313C10722A8301D00FF2AFB /* CameraView.swift */; };
C34D712822A9B14700E60D50 /* CameraViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C34D712722A9B14700E60D50 /* CameraViewController.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
C313C0B422A6FBAC00FF2AFB /* Instagram-SWUI.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Instagram-SWUI.app"; sourceTree = BUILT_PRODUCTS_DIR; };
C313C0B722A6FBAC00FF2AFB /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
C313C0B922A6FBAC00FF2AFB /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
C313C0BC22A6FBAC00FF2AFB /* Instagram_SWUI.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Instagram_SWUI.xcdatamodel; sourceTree = "<group>"; };
C313C0BE22A6FBAC00FF2AFB /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
C313C0C022A6FBAE00FF2AFB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
C313C0C322A6FBAE00FF2AFB /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
C313C0C622A6FBAE00FF2AFB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
C313C0C822A6FBAE00FF2AFB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
C313C0F322A727EE00FF2AFB /* InstaPhoto.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstaPhoto.swift; sourceTree = "<group>"; };
C313C10122A778D100FF2AFB /* PhotoLibrary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoLibrary.swift; sourceTree = "<group>"; };
C313C10722A8301D00FF2AFB /* CameraView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraView.swift; sourceTree = "<group>"; };
C34D712722A9B14700E60D50 /* CameraViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraViewController.swift; sourceTree = "<group>"; };
C34D712922A9C1CF00E60D50 /* Instagram-SWUI.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Instagram-SWUI.entitlements"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
C313C0B122A6FBAC00FF2AFB /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
C313C0AB22A6FBAC00FF2AFB = {
isa = PBXGroup;
children = (
C313C0B622A6FBAC00FF2AFB /* Instagram-SWUI */,
C313C0B522A6FBAC00FF2AFB /* Products */,
);
sourceTree = "<group>";
};
C313C0B522A6FBAC00FF2AFB /* Products */ = {
isa = PBXGroup;
children = (
C313C0B422A6FBAC00FF2AFB /* Instagram-SWUI.app */,
);
name = Products;
sourceTree = "<group>";
};
C313C0B622A6FBAC00FF2AFB /* Instagram-SWUI */ = {
isa = PBXGroup;
children = (
C34D712922A9C1CF00E60D50 /* Instagram-SWUI.entitlements */,
C313C0B722A6FBAC00FF2AFB /* AppDelegate.swift */,
C313C0B922A6FBAC00FF2AFB /* SceneDelegate.swift */,
C34D712722A9B14700E60D50 /* CameraViewController.swift */,
C313C0BE22A6FBAC00FF2AFB /* ContentView.swift */,
C313C10722A8301D00FF2AFB /* CameraView.swift */,
C313C0F322A727EE00FF2AFB /* InstaPhoto.swift */,
C313C10122A778D100FF2AFB /* PhotoLibrary.swift */,
C313C0C022A6FBAE00FF2AFB /* Assets.xcassets */,
C313C0C522A6FBAE00FF2AFB /* LaunchScreen.storyboard */,
C313C0C822A6FBAE00FF2AFB /* Info.plist */,
C313C0BB22A6FBAC00FF2AFB /* Instagram_SWUI.xcdatamodeld */,
C313C0C222A6FBAE00FF2AFB /* Preview Content */,
);
path = "Instagram-SWUI";
sourceTree = "<group>";
};
C313C0C222A6FBAE00FF2AFB /* Preview Content */ = {
isa = PBXGroup;
children = (
C313C0C322A6FBAE00FF2AFB /* Preview Assets.xcassets */,
);
path = "Preview Content";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
C313C0B322A6FBAC00FF2AFB /* Instagram-SWUI */ = {
isa = PBXNativeTarget;
buildConfigurationList = C313C0CB22A6FBAE00FF2AFB /* Build configuration list for PBXNativeTarget "Instagram-SWUI" */;
buildPhases = (
C313C0B022A6FBAC00FF2AFB /* Sources */,
C313C0B122A6FBAC00FF2AFB /* Frameworks */,
C313C0B222A6FBAC00FF2AFB /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "Instagram-SWUI";
productName = "Instagram-SWUI";
productReference = C313C0B422A6FBAC00FF2AFB /* Instagram-SWUI.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
C313C0AC22A6FBAC00FF2AFB /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1100;
LastUpgradeCheck = 1100;
ORGANIZATIONNAME = "leavenstee llc";
TargetAttributes = {
C313C0B322A6FBAC00FF2AFB = {
CreatedOnToolsVersion = 11.0;
};
};
};
buildConfigurationList = C313C0AF22A6FBAC00FF2AFB /* Build configuration list for PBXProject "Instagram-SWUI" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = C313C0AB22A6FBAC00FF2AFB;
productRefGroup = C313C0B522A6FBAC00FF2AFB /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
C313C0B322A6FBAC00FF2AFB /* Instagram-SWUI */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
C313C0B222A6FBAC00FF2AFB /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C313C0C722A6FBAE00FF2AFB /* LaunchScreen.storyboard in Resources */,
C313C0C422A6FBAE00FF2AFB /* Preview Assets.xcassets in Resources */,
C313C0C122A6FBAE00FF2AFB /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
C313C0B022A6FBAC00FF2AFB /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C313C0B822A6FBAC00FF2AFB /* AppDelegate.swift in Sources */,
C313C0BD22A6FBAC00FF2AFB /* Instagram_SWUI.xcdatamodeld in Sources */,
C313C0F422A727EE00FF2AFB /* InstaPhoto.swift in Sources */,
C313C10222A778D100FF2AFB /* PhotoLibrary.swift in Sources */,
C313C0BF22A6FBAC00FF2AFB /* ContentView.swift in Sources */,
C34D712822A9B14700E60D50 /* CameraViewController.swift in Sources */,
C313C0BA22A6FBAC00FF2AFB /* SceneDelegate.swift in Sources */,
C313C10822A8301D00FF2AFB /* CameraView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
C313C0C522A6FBAE00FF2AFB /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
C313C0C622A6FBAE00FF2AFB /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
C313C0C922A6FBAE00FF2AFB /* 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;
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 = 13.0;
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;
};
C313C0CA22A6FBAE00FF2AFB /* 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;
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 = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
C313C0CC22A6FBAE00FF2AFB /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "Instagram-SWUI/Instagram-SWUI.entitlements";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "Instagram-SWUI/Preview\\ Content";
DEVELOPMENT_TEAM = D846Q7V7YL;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = "Instagram-SWUI/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = "leavenstee.Instagram-SWUI";
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTS_UIKITFORMAC = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
C313C0CD22A6FBAE00FF2AFB /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "Instagram-SWUI/Instagram-SWUI.entitlements";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "Instagram-SWUI/Preview\\ Content";
DEVELOPMENT_TEAM = D846Q7V7YL;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = "Instagram-SWUI/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = "leavenstee.Instagram-SWUI";
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTS_UIKITFORMAC = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
C313C0AF22A6FBAC00FF2AFB /* Build configuration list for PBXProject "Instagram-SWUI" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C313C0C922A6FBAE00FF2AFB /* Debug */,
C313C0CA22A6FBAE00FF2AFB /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
C313C0CB22A6FBAE00FF2AFB /* Build configuration list for PBXNativeTarget "Instagram-SWUI" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C313C0CC22A6FBAE00FF2AFB /* Debug */,
C313C0CD22A6FBAE00FF2AFB /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCVersionGroup section */
C313C0BB22A6FBAC00FF2AFB /* Instagram_SWUI.xcdatamodeld */ = {
isa = XCVersionGroup;
children = (
C313C0BC22A6FBAC00FF2AFB /* Instagram_SWUI.xcdatamodel */,
);
currentVersion = C313C0BC22A6FBAC00FF2AFB /* Instagram_SWUI.xcdatamodel */;
path = Instagram_SWUI.xcdatamodeld;
sourceTree = "<group>";
versionGroupType = wrapper.xcdatamodel;
};
/* End XCVersionGroup section */
};
rootObject = C313C0AC22A6FBAC00FF2AFB /* Project object */;
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Instagram-SWUI.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -0,0 +1,8 @@
<?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>

View File

@@ -0,0 +1,88 @@
//
// AppDelegate.swift
// Instagram-SWUI
//
// Created by Steven Lee on 6/4/19.
// Copyright © 2019 leavenstee llc. All rights reserved.
//
import UIKit
import CoreData
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
// Saves changes in the application's managed object context before the application terminates.
self.saveContext()
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentContainer = {
/*
The persistent container for the application. This implementation
creates and returns a container, having loaded the store for the
application to it. This property is optional since there are legitimate
error conditions that could cause the creation of the store to fail.
*/
let container = NSPersistentContainer(name: "Instagram_SWUI")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
* The device is out of space.
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
// MARK: - Core Data Saving support
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
}

View File

@@ -0,0 +1,98 @@
{
"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"
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "58120000553__7091B1D4-F645-4760-B5EE-D38E53D53F54.JPG",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "IMG_0163.jpeg",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

View File

@@ -0,0 +1,15 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "photo-camera.png"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "original"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "IMG_0156.jpeg",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

View File

@@ -0,0 +1,12 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "wwdc.JPG"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

View File

@@ -0,0 +1,25 @@
<?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" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<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>

View File

@@ -0,0 +1,25 @@
//
// CameraView.swift
// Instagram-SWUI
//
// Created by Steven Lee on 6/5/19.
// Copyright © 2019 leavenstee llc. All rights reserved.
//
import SwiftUI
import UIKit
struct CameraView : UIViewControllerRepresentable {
func makeUIViewController(context: UIViewControllerRepresentableContext<CameraView>) -> CameraViewController {
return CameraViewController()
}
func updateUIViewController(_ uiViewController: CameraViewController, context: UIViewControllerRepresentableContext<CameraView>) {
}
typealias UIViewControllerType = CameraViewController
}

View File

@@ -0,0 +1,152 @@
//
// CameraViewController.swift
// Instagram-SWUI
//
// Created by Steven Lee on 6/6/19.
// Copyright © 2019 leavenstee llc. All rights reserved.
//
import UIKit
import AVFoundation
class CameraViewController: UIViewController {
var previewView: UIView!
var captureButton: UIButton!
var captureSession: AVCaptureSession?
var videoPreviewLayer: AVCaptureVideoPreviewLayer?
var capturePhotoOutput: AVCapturePhotoOutput?
var qrCodeFrameView: UIView?
override func viewDidLoad() {
super.viewDidLoad()
previewView = UIView(frame: view.frame)
captureButton = UIButton(frame: CGRect(x: 100, y: 100, width: 300, height: 300))
captureButton.backgroundColor = .green
captureButton.layer.cornerRadius = captureButton.frame.size.width / 2
captureButton.clipsToBounds = true
// Get an instance of the AVCaptureDevice class to initialize a device object and provide the video as the media type parameter
guard let captureDevice = AVCaptureDevice.default(for: .video) else {
fatalError("No video device found")
}
do {
// Get an instance of the AVCaptureDeviceInput class using the previous deivce object
let input = try AVCaptureDeviceInput(device: captureDevice)
// Initialize the captureSession object
captureSession = AVCaptureSession()
// Set the input devcie on the capture session
captureSession?.addInput(input)
// Get an instance of ACCapturePhotoOutput class
capturePhotoOutput = AVCapturePhotoOutput()
capturePhotoOutput?.isHighResolutionCaptureEnabled = true
// Set the output on the capture session
captureSession?.addOutput(capturePhotoOutput!)
// Initialize a AVCaptureMetadataOutput object and set it as the input device
let captureMetadataOutput = AVCaptureMetadataOutput()
captureSession?.addOutput(captureMetadataOutput)
//Initialise the video preview layer and add it as a sublayer to the viewPreview view's layer
videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession!)
videoPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
videoPreviewLayer?.frame = view.layer.bounds
previewView.layer.addSublayer(videoPreviewLayer!)
//start video capture
captureSession?.startRunning()
//Initialize QR Code Frame to highlight the QR code
qrCodeFrameView = UIView()
if let qrCodeFrameView = qrCodeFrameView {
qrCodeFrameView.layer.borderColor = UIColor.green.cgColor
qrCodeFrameView.layer.borderWidth = 2
view.addSubview(qrCodeFrameView)
view.bringSubviewToFront(qrCodeFrameView)
}
} catch {
//If any error occurs, simply print it out
print(error)
return
}
}
override func viewDidLayoutSubviews() {
videoPreviewLayer?.frame = view.bounds
if let previewLayer = videoPreviewLayer ,(previewLayer.connection?.isVideoOrientationSupported)! {
previewLayer.connection?.videoOrientation = UIApplication.shared.statusBarOrientation.videoOrientation ?? .portrait
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func onTapTakePhoto(_ sender: Any) {
// Make sure capturePhotoOutput is valid
guard let capturePhotoOutput = self.capturePhotoOutput else { return }
// Get an instance of AVCapturePhotoSettings class
let photoSettings = AVCapturePhotoSettings()
// Set photo settings for our need
photoSettings.isAutoStillImageStabilizationEnabled = true
photoSettings.isHighResolutionPhotoEnabled = true
photoSettings.flashMode = .auto
// Call capturePhoto method by passing our photo settings and a delegate implementing AVCapturePhotoCaptureDelegate
capturePhotoOutput.capturePhoto(with: photoSettings, delegate: self)
}
}
extension CameraViewController : AVCapturePhotoCaptureDelegate {
func photoOutput(_ captureOutput: AVCapturePhotoOutput,
didFinishProcessingPhoto photoSampleBuffer: CMSampleBuffer?,
previewPhoto previewPhotoSampleBuffer: CMSampleBuffer?,
resolvedSettings: AVCaptureResolvedPhotoSettings,
bracketSettings: AVCaptureBracketedStillImageSettings?,
error: Error?) {
// Make sure we get some photo sample buffer
guard error == nil,
let photoSampleBuffer = photoSampleBuffer else {
print("Error capturing photo: \(String(describing: error))")
return
}
// Convert photo same buffer to a jpeg image data by using AVCapturePhotoOutput
guard let imageData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoSampleBuffer, previewPhotoSampleBuffer: previewPhotoSampleBuffer) else {
return
}
// Initialise an UIImage with our image data
let capturedImage = UIImage.init(data: imageData , scale: 1.0)
if let image = capturedImage {
// Save our captured image to photos album
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
}
}
}
extension UIInterfaceOrientation {
var videoOrientation: AVCaptureVideoOrientation? {
switch self {
case .portraitUpsideDown: return .portraitUpsideDown
case .landscapeRight: return .landscapeRight
case .landscapeLeft: return .landscapeLeft
case .portrait: return .portrait
default: return nil
}
}
}

View File

@@ -0,0 +1,116 @@
//
// ContentView.swift
// Instagram-SWUI
//
// Created by Steven Lee on 6/4/19.
// Copyright © 2019 leavenstee llc. All rights reserved.
//
import SwiftUI
import AVKit
import CoreLocation
struct ContentView : View {
var instaPhotos: [InstaPhoto]
var body: some View {
NavigationView {
List {
ForEach(instaPhotos.identified(by: \.id)) {
ImageCell(photo: $0)
}
}.navigationBarTitle(Text("WWDC")).navigationBarItems(trailing: PresentationButton(Text("Camera"), destination: CameraView()))
}
}
func takePhoto() {
// Open Camera
}
}
#if DEBUG
struct ContentView_Previews : PreviewProvider {
static var previews: some View {
ContentView(instaPhotos: [InstaPhoto(id: 0, username: "leavenstee", comments: ["Nice", "Cool","Lame"], likes: 100, image: "wwdc"),InstaPhoto(id: 0, username: "leavenstee", comments: ["Nice", "Cool","Lame","Nice", "Cool","Lame"], likes: 200, image: "pizza"),
InstaPhoto(id: 0, username: "leavenstee", comments: ["Nice", "Cool","Lame","Nice", "Cool","Lame","Nice", "Cool","Lame","Nice", "Cool","Lame"], likes: 4440, image: "wwdc"),InstaPhoto(id: 0, username: "leavenstee", comments: ["Nice", "Cool"], likes: 20, image: "badge")])
}
}
#endif
struct ImageCell : View {
@State var expanded = false
@State var liked = false
var photo: InstaPhoto
var body: some View {
return VStack(alignment: .leading) {
HStack {
Image("badge").resizable().scaledToFit().cornerRadius(100)
Text(photo.username)
Button(action: {}, label: {
Text("...")
})
}.frame(height: 40)
Image(photo.image)
.resizable()
.scaledToFit()
.cornerRadius(10)
// Control Buttons
HStack {
Button(action: withAnimation { likeButtonPressed }, label: {
Text( self.liked ? "❤️" :"💔")
})
Button(action: commentButtonPressed, label: {
Text("🗣")
})
Button(action: likeButtonPressed, label: {
Text("📪")
})
Spacer()
Button(action: likeButtonPressed, label: {
Text("📕")
})
}
Text("\(photo.likes) Likes")
.multilineTextAlignment(.leading)
Text(photo.username)
.multilineTextAlignment(.leading)
Button(action: moreCommentsPressed, label: {
Text("View All \(photo.comments.count) Comments")
.fontWeight(.light)
})
if expanded {
VStack {
Text("Test Comment")
Text("Test Comment")
Text("Test Comment")
Text("Test Comment")
}
}
}
}
func moreCommentsPressed() {
expanded.toggle()
}
func likeButtonPressed() {
liked.toggle()
}
func commentButtonPressed() {
}
func shareButtonPressed() {
}
func bookMarkButtonPressed() {
}
}

View File

@@ -0,0 +1,64 @@
<?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>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>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>NSCameraUsageDescription</key>
<string>Let me use your camer for pics</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
</dict>
</array>
</dict>
</dict>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</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>
</dict>
</plist>

View File

@@ -0,0 +1,18 @@
//
// InstaPhoto.swift
// Instagram-SWUI
//
// Created by Steven Lee on 6/4/19.
// Copyright © 2019 leavenstee llc. All rights reserved.
//
import Foundation
import SwiftUI
struct InstaPhoto: Identifiable {
let id: Int
let username: String
let comments: [String]
let likes: Int
let image: String
}

View File

@@ -0,0 +1,12 @@
<?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>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,8 @@
<?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>_XCCurrentVersionName</key>
<string>Instagram_SWUI.xcdatamodel</string>
</dict>
</plist>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="1" systemVersion="11A491" minimumToolsVersion="Automatic" sourceLanguage="Swift" usedWithCloudKit="false" userDefinedModelVersionIdentifier="">
<elements/>
</model>

View File

@@ -0,0 +1,13 @@
//
// PhotoLibrary.swift
// Instagram-SWUI
//
// Created by Steven Lee on 6/4/19.
// Copyright © 2019 leavenstee llc. All rights reserved.
//
import Foundation
struct PhotoLibrary {
let photos: [InstaPhoto]
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -0,0 +1,63 @@
//
// SceneDelegate.swift
// Instagram-SWUI
//
// Created by Steven Lee on 6/4/19.
// Copyright © 2019 leavenstee llc. All rights reserved.
//
import UIKit
import SwiftUI
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
// Use a UIHostingController as window root view controller
let window = UIWindow(frame: UIScreen.main.bounds)
window.rootViewController = UIHostingController(rootView: ContentView(instaPhotos: [InstaPhoto(id: 0, username: "leavenstee", comments: ["Nice", "Cool","Lame"], likes: 100, image: "wwdc"),InstaPhoto(id: 0, username: "leavenstee", comments: ["Nice", "Cool","Lame","Nice", "Cool","Lame"], likes: 200, image: "pizza"),
InstaPhoto(id: 0, username: "leavenstee", comments: ["Nice", "Cool","Lame","Nice", "Cool","Lame","Nice", "Cool","Lame","Nice", "Cool","Lame"], likes: 4440, image: "wwdc"),InstaPhoto(id: 0, username: "leavenstee", comments: ["Nice", "Cool"], likes: 20, image: "badge")]))
self.window = window
window.makeKeyAndVisible()
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
// Save changes in the application's managed object context when the application transitions to the background.
(UIApplication.shared.delegate as? AppDelegate)?.saveContext()
}
}

View File

@@ -0,0 +1,451 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
69FFAF8022A99F1100801F3C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAF7F22A99F1100801F3C /* AppDelegate.swift */; };
69FFAF8222A99F1100801F3C /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAF8122A99F1100801F3C /* SceneDelegate.swift */; };
69FFAF8422A99F1100801F3C /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAF8322A99F1100801F3C /* ContentView.swift */; };
69FFAF8622A99F1200801F3C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 69FFAF8522A99F1200801F3C /* Assets.xcassets */; };
69FFAF8922A99F1200801F3C /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 69FFAF8822A99F1200801F3C /* Preview Assets.xcassets */; };
69FFAF8C22A99F1200801F3C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 69FFAF8A22A99F1200801F3C /* LaunchScreen.storyboard */; };
69FFAF9822A9A12800801F3C /* APIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAF9722A9A12800801F3C /* APIService.swift */; };
69FFAF9B22A9A66200801F3C /* Movie.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAF9A22A9A66200801F3C /* Movie.swift */; };
69FFAF9D22A9A6D500801F3C /* PaginatedResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAF9C22A9A6D500801F3C /* PaginatedResponse.swift */; };
69FFAFA122A9A9F600801F3C /* Reducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAFA022A9A9F600801F3C /* Reducer.swift */; };
69FFAFA422A9AA2600801F3C /* Action.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAFA322A9AA2600801F3C /* Action.swift */; };
69FFAFA622A9AA3500801F3C /* FluxState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAFA522A9AA3500801F3C /* FluxState.swift */; };
69FFAFA822A9AA4900801F3C /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAFA722A9AA4900801F3C /* AppState.swift */; };
69FFAFAA22A9AA6500801F3C /* MoviesState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAFA922A9AA6500801F3C /* MoviesState.swift */; };
69FFAFAC22A9AABB00801F3C /* MoviesStateReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAFAB22A9AABB00801F3C /* MoviesStateReducer.swift */; };
69FFAFAE22A9AB1D00801F3C /* MoviesAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAFAD22A9AB1D00801F3C /* MoviesAction.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
69FFAF7C22A99F1100801F3C /* MovieSwift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MovieSwift.app; sourceTree = BUILT_PRODUCTS_DIR; };
69FFAF7F22A99F1100801F3C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
69FFAF8122A99F1100801F3C /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
69FFAF8322A99F1100801F3C /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
69FFAF8522A99F1200801F3C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
69FFAF8822A99F1200801F3C /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
69FFAF8B22A99F1200801F3C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
69FFAF8D22A99F1200801F3C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
69FFAF9722A9A12800801F3C /* APIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIService.swift; sourceTree = "<group>"; };
69FFAF9A22A9A66200801F3C /* Movie.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Movie.swift; sourceTree = "<group>"; };
69FFAF9C22A9A6D500801F3C /* PaginatedResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaginatedResponse.swift; sourceTree = "<group>"; };
69FFAFA022A9A9F600801F3C /* Reducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Reducer.swift; sourceTree = "<group>"; };
69FFAFA322A9AA2600801F3C /* Action.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Action.swift; sourceTree = "<group>"; };
69FFAFA522A9AA3500801F3C /* FluxState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FluxState.swift; sourceTree = "<group>"; };
69FFAFA722A9AA4900801F3C /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = "<group>"; };
69FFAFA922A9AA6500801F3C /* MoviesState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoviesState.swift; sourceTree = "<group>"; };
69FFAFAB22A9AABB00801F3C /* MoviesStateReducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoviesStateReducer.swift; sourceTree = "<group>"; };
69FFAFAD22A9AB1D00801F3C /* MoviesAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoviesAction.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
69FFAF7922A99F1100801F3C /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
69FFAF7322A99F1100801F3C = {
isa = PBXGroup;
children = (
69FFAF7E22A99F1100801F3C /* MovieSwift */,
69FFAF7D22A99F1100801F3C /* Products */,
);
sourceTree = "<group>";
};
69FFAF7D22A99F1100801F3C /* Products */ = {
isa = PBXGroup;
children = (
69FFAF7C22A99F1100801F3C /* MovieSwift.app */,
);
name = Products;
sourceTree = "<group>";
};
69FFAF7E22A99F1100801F3C /* MovieSwift */ = {
isa = PBXGroup;
children = (
69FFAF9322A9A0D800801F3C /* launch */,
69FFAF9522A9A0E300801F3C /* flux */,
69FFAF9622A9A11A00801F3C /* services */,
69FFAF9422A9A0DF00801F3C /* views */,
69FFAF8522A99F1200801F3C /* Assets.xcassets */,
69FFAF8A22A99F1200801F3C /* LaunchScreen.storyboard */,
69FFAF8D22A99F1200801F3C /* Info.plist */,
69FFAF8722A99F1200801F3C /* Preview Content */,
);
path = MovieSwift;
sourceTree = "<group>";
};
69FFAF8722A99F1200801F3C /* Preview Content */ = {
isa = PBXGroup;
children = (
69FFAF8822A99F1200801F3C /* Preview Assets.xcassets */,
);
path = "Preview Content";
sourceTree = "<group>";
};
69FFAF9322A9A0D800801F3C /* launch */ = {
isa = PBXGroup;
children = (
69FFAF7F22A99F1100801F3C /* AppDelegate.swift */,
69FFAF8122A99F1100801F3C /* SceneDelegate.swift */,
);
path = launch;
sourceTree = "<group>";
};
69FFAF9422A9A0DF00801F3C /* views */ = {
isa = PBXGroup;
children = (
69FFAF8322A99F1100801F3C /* ContentView.swift */,
);
path = views;
sourceTree = "<group>";
};
69FFAF9522A9A0E300801F3C /* flux */ = {
isa = PBXGroup;
children = (
69FFAFA222A9AA1E00801F3C /* actions */,
69FFAF9F22A9A9E600801F3C /* reducers */,
69FFAF9E22A9A9D400801F3C /* state */,
69FFAF9922A9A1AE00801F3C /* models */,
);
path = flux;
sourceTree = "<group>";
};
69FFAF9622A9A11A00801F3C /* services */ = {
isa = PBXGroup;
children = (
69FFAF9722A9A12800801F3C /* APIService.swift */,
);
path = services;
sourceTree = "<group>";
};
69FFAF9922A9A1AE00801F3C /* models */ = {
isa = PBXGroup;
children = (
69FFAF9A22A9A66200801F3C /* Movie.swift */,
69FFAF9C22A9A6D500801F3C /* PaginatedResponse.swift */,
);
path = models;
sourceTree = "<group>";
};
69FFAF9E22A9A9D400801F3C /* state */ = {
isa = PBXGroup;
children = (
69FFAFA522A9AA3500801F3C /* FluxState.swift */,
69FFAFA722A9AA4900801F3C /* AppState.swift */,
69FFAFA922A9AA6500801F3C /* MoviesState.swift */,
);
path = state;
sourceTree = "<group>";
};
69FFAF9F22A9A9E600801F3C /* reducers */ = {
isa = PBXGroup;
children = (
69FFAFA022A9A9F600801F3C /* Reducer.swift */,
69FFAFAB22A9AABB00801F3C /* MoviesStateReducer.swift */,
);
path = reducers;
sourceTree = "<group>";
};
69FFAFA222A9AA1E00801F3C /* actions */ = {
isa = PBXGroup;
children = (
69FFAFA322A9AA2600801F3C /* Action.swift */,
69FFAFAD22A9AB1D00801F3C /* MoviesAction.swift */,
);
path = actions;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
69FFAF7B22A99F1100801F3C /* MovieSwift */ = {
isa = PBXNativeTarget;
buildConfigurationList = 69FFAF9022A99F1200801F3C /* Build configuration list for PBXNativeTarget "MovieSwift" */;
buildPhases = (
69FFAF7822A99F1100801F3C /* Sources */,
69FFAF7922A99F1100801F3C /* Frameworks */,
69FFAF7A22A99F1100801F3C /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = MovieSwift;
productName = MovieSwift;
productReference = 69FFAF7C22A99F1100801F3C /* MovieSwift.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
69FFAF7422A99F1100801F3C /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1100;
LastUpgradeCheck = 1100;
ORGANIZATIONNAME = "Thomas Ricouard";
TargetAttributes = {
69FFAF7B22A99F1100801F3C = {
CreatedOnToolsVersion = 11.0;
};
};
};
buildConfigurationList = 69FFAF7722A99F1100801F3C /* Build configuration list for PBXProject "MovieSwift" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 69FFAF7322A99F1100801F3C;
productRefGroup = 69FFAF7D22A99F1100801F3C /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
69FFAF7B22A99F1100801F3C /* MovieSwift */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
69FFAF7A22A99F1100801F3C /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
69FFAF8C22A99F1200801F3C /* LaunchScreen.storyboard in Resources */,
69FFAF8922A99F1200801F3C /* Preview Assets.xcassets in Resources */,
69FFAF8622A99F1200801F3C /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
69FFAF7822A99F1100801F3C /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
69FFAF8022A99F1100801F3C /* AppDelegate.swift in Sources */,
69FFAFA822A9AA4900801F3C /* AppState.swift in Sources */,
69FFAF8222A99F1100801F3C /* SceneDelegate.swift in Sources */,
69FFAF9D22A9A6D500801F3C /* PaginatedResponse.swift in Sources */,
69FFAF9822A9A12800801F3C /* APIService.swift in Sources */,
69FFAFA122A9A9F600801F3C /* Reducer.swift in Sources */,
69FFAFA422A9AA2600801F3C /* Action.swift in Sources */,
69FFAF8422A99F1100801F3C /* ContentView.swift in Sources */,
69FFAFA622A9AA3500801F3C /* FluxState.swift in Sources */,
69FFAFAC22A9AABB00801F3C /* MoviesStateReducer.swift in Sources */,
69FFAFAA22A9AA6500801F3C /* MoviesState.swift in Sources */,
69FFAF9B22A9A66200801F3C /* Movie.swift in Sources */,
69FFAFAE22A9AB1D00801F3C /* MoviesAction.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
69FFAF8A22A99F1200801F3C /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
69FFAF8B22A99F1200801F3C /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
69FFAF8E22A99F1200801F3C /* 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;
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 = 13.0;
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;
};
69FFAF8F22A99F1200801F3C /* 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;
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 = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
69FFAF9122A99F1200801F3C /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "MovieSwift/Preview\\ Content";
DEVELOPMENT_TEAM = Z6P74P6T99;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = MovieSwift/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.thomasricouard.MovieSwift;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
69FFAF9222A99F1200801F3C /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "MovieSwift/Preview\\ Content";
DEVELOPMENT_TEAM = Z6P74P6T99;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = MovieSwift/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.thomasricouard.MovieSwift;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
69FFAF7722A99F1100801F3C /* Build configuration list for PBXProject "MovieSwift" */ = {
isa = XCConfigurationList;
buildConfigurations = (
69FFAF8E22A99F1200801F3C /* Debug */,
69FFAF8F22A99F1200801F3C /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
69FFAF9022A99F1200801F3C /* Build configuration list for PBXNativeTarget "MovieSwift" */ = {
isa = XCConfigurationList;
buildConfigurations = (
69FFAF9122A99F1200801F3C /* Debug */,
69FFAF9222A99F1200801F3C /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 69FFAF7422A99F1100801F3C /* Project object */;
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:MovieSwift.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -0,0 +1,8 @@
<?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>

View File

@@ -0,0 +1,98 @@
{
"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"
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -0,0 +1,25 @@
<?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" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<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>

View File

@@ -0,0 +1,62 @@
<?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>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>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
</dict>
</array>
</dict>
</dict>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</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>
</dict>
</plist>

View File

@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -0,0 +1,13 @@
//
// Action.swift
// MovieSwift
//
// Created by Thomas Ricouard on 06/06/2019.
// Copyright © 2019 Thomas Ricouard. All rights reserved.
//
import Foundation
protocol Action {
}

View File

@@ -0,0 +1,29 @@
//
// MoviesAction.swift
// MovieSwift
//
// Created by Thomas Ricouard on 06/06/2019.
// Copyright © 2019 Thomas Ricouard. All rights reserved.
//
import Foundation
struct MoviesActions {
struct FetchPopular: Action {
init() {
APIService.shared.GET(endpoint: .popular, params: nil) {
(result: Result<PaginatedResponse<Movie>, APIService.APIError>) in
switch result {
case let .success(response):
store.dispatch(action: SetPopular(response: response))
case .failure(_):
break
}
}
}
}
struct SetPopular: Action {
let response: PaginatedResponse<Movie>
}
}

View File

@@ -0,0 +1,14 @@
//
// Movie.swift
// MovieSwift
//
// Created by Thomas Ricouard on 06/06/2019.
// Copyright © 2019 Thomas Ricouard. All rights reserved.
//
import Foundation
struct Movie: Codable {
let id: Int
let original_title: String
}

View File

@@ -0,0 +1,16 @@
//
// PaginatedResponse.swift
// MovieSwift
//
// Created by Thomas Ricouard on 06/06/2019.
// Copyright © 2019 Thomas Ricouard. All rights reserved.
//
import Foundation
struct PaginatedResponse<T: Codable>: Codable {
let page: Int
let total_results: Int
let total_pages: Int
let results: [T]
}

View File

@@ -0,0 +1,22 @@
//
// MoviesStateReducer.swift
// MovieSwift
//
// Created by Thomas Ricouard on 06/06/2019.
// Copyright © 2019 Thomas Ricouard. All rights reserved.
//
import Foundation
struct MoviesStateReducer: Reducer {
func reduce(state: MoviesState, action: Action) -> MoviesState {
var state = state
if let action = action as? MoviesActions.SetPopular {
state.popular = action.response.results.map{ $0.id }
for (_, value) in action.response.results.enumerated() {
state.movies[value.id] = value
}
}
return state
}
}

View File

@@ -0,0 +1,14 @@
//
// Reducer.swift
// MovieSwift
//
// Created by Thomas Ricouard on 06/06/2019.
// Copyright © 2019 Thomas Ricouard. All rights reserved.
//
import Foundation
protocol Reducer {
associatedtype StateType: FluxState
func reduce(state: StateType, action: Action) -> StateType
}

View File

@@ -0,0 +1,28 @@
//
// AppState.swift
// MovieSwift
//
// Created by Thomas Ricouard on 06/06/2019.
// Copyright © 2019 Thomas Ricouard. All rights reserved.
//
import Foundation
import SwiftUI
import Combine
final class AppState: BindableObject {
var didChange = PassthroughSubject<AppState, Never>()
var moviesState: MoviesState
init(moviesState: MoviesState = MoviesState()) {
self.moviesState = moviesState
}
func dispatch(action: Action) {
moviesState = MoviesStateReducer().reduce(state: moviesState, action: action)
didChange.send(self)
}
}
let store = AppState()

View File

@@ -0,0 +1,13 @@
//
// FluxState.swift
// MovieSwift
//
// Created by Thomas Ricouard on 06/06/2019.
// Copyright © 2019 Thomas Ricouard. All rights reserved.
//
import Foundation
protocol FluxState {
}

View File

@@ -0,0 +1,14 @@
//
// MoviesState.swift
// MovieSwift
//
// Created by Thomas Ricouard on 06/06/2019.
// Copyright © 2019 Thomas Ricouard. All rights reserved.
//
import Foundation
struct MoviesState: FluxState {
var movies: [Int: Movie] = [:]
var popular: [Int] = []
}

View File

@@ -0,0 +1,41 @@
//
// AppDelegate.swift
// MovieSwift
//
// Created by Thomas Ricouard on 06/06/2019.
// Copyright © 2019 Thomas Ricouard. All rights reserved.
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}

View File

@@ -0,0 +1,59 @@
//
// SceneDelegate.swift
// MovieSwift
//
// Created by Thomas Ricouard on 06/06/2019.
// Copyright © 2019 Thomas Ricouard. All rights reserved.
//
import UIKit
import SwiftUI
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
// Use a UIHostingController as window root view controller
let window = UIWindow(frame: UIScreen.main.bounds)
window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(store))
self.window = window
window.makeKeyAndVisible()
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
}
}

View File

@@ -0,0 +1,68 @@
//
// APIService.swift
// MovieSwift
//
// Created by Thomas Ricouard on 06/06/2019.
// Copyright © 2019 Thomas Ricouard. All rights reserved.
//
import Foundation
struct APIService {
let baseURL = URL(string: "https://api.themoviedb.org/3")!
let apiKey = "1d9b898a212ea52e283351e521e17871"
static let shared = APIService()
let decoder = JSONDecoder()
enum APIError: Error {
case noResponse
case jsonDecodingError(error: Error)
case networkError(error: Error)
}
enum Endpoint {
case popular
func path() -> String {
switch self {
case .popular:
return "movie/popular"
}
}
}
func GET<T: Codable>(endpoint: Endpoint,
params: [String: String]?,
completionHandler: @escaping (Result<T, APIError>) -> Void) {
let queryURL = baseURL.appendingPathComponent(endpoint.path())
var components = URLComponents(url: queryURL, resolvingAgainstBaseURL: true)!
components.queryItems = [
URLQueryItem(name: "api_key", value: apiKey)
]
if let params = params {
for (_, value) in params.enumerated() {
components.queryItems?.append(URLQueryItem(name: value.key, value: value.value))
}
}
var request = URLRequest(url: components.url!)
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data else {
completionHandler(.failure(.noResponse))
return
}
guard error == nil else {
completionHandler(.failure(.networkError(error: error!)))
return
}
do {
let object = try self.decoder.decode(T.self, from: data)
completionHandler(.success(object))
} catch let error {
completionHandler(.failure(.jsonDecodingError(error: error)))
}
}
task.resume()
}
}

View File

@@ -0,0 +1,33 @@
//
// ContentView.swift
// MovieSwift
//
// Created by Thomas Ricouard on 06/06/2019.
// Copyright © 2019 Thomas Ricouard. All rights reserved.
//
import SwiftUI
struct ContentView : View {
@EnvironmentObject var state: AppState
init() {
store.dispatch(action: MoviesActions.FetchPopular())
}
var body: some View {
List {
ForEach(state.moviesState.popular) { id in
Text(self.state.moviesState.movies[id]?.original_title ?? "No title")
}
}
}
}
#if DEBUG
struct ContentView_Previews : PreviewProvider {
static var previews: some View {
ContentView()
}
}
#endif

View File

@@ -0,0 +1,351 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
96A09A3F22AA0F3A00FE6BC6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96A09A3E22AA0F3A00FE6BC6 /* AppDelegate.swift */; };
96A09A4122AA0F3A00FE6BC6 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96A09A4022AA0F3A00FE6BC6 /* SceneDelegate.swift */; };
96A09A4522AA0F3D00FE6BC6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 96A09A4422AA0F3D00FE6BC6 /* Assets.xcassets */; };
96A09A4822AA0F3D00FE6BC6 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 96A09A4722AA0F3D00FE6BC6 /* Preview Assets.xcassets */; };
96A09A4B22AA0F3D00FE6BC6 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 96A09A4922AA0F3D00FE6BC6 /* LaunchScreen.storyboard */; };
96A09A6F22AA110600FE6BC6 /* Home.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96A09A6E22AA110600FE6BC6 /* Home.swift */; };
96A09A7122AA11D600FE6BC6 /* ClockView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96A09A7022AA11D600FE6BC6 /* ClockView.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
96A09A3B22AA0F3A00FE6BC6 /* TempusRomanum.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TempusRomanum.app; sourceTree = BUILT_PRODUCTS_DIR; };
96A09A3E22AA0F3A00FE6BC6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
96A09A4022AA0F3A00FE6BC6 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
96A09A4422AA0F3D00FE6BC6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
96A09A4722AA0F3D00FE6BC6 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
96A09A4A22AA0F3D00FE6BC6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
96A09A4C22AA0F3D00FE6BC6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
96A09A6E22AA110600FE6BC6 /* Home.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Home.swift; sourceTree = "<group>"; };
96A09A7022AA11D600FE6BC6 /* ClockView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClockView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
96A09A3822AA0F3A00FE6BC6 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
96A09A3222AA0F3A00FE6BC6 = {
isa = PBXGroup;
children = (
96A09A3D22AA0F3A00FE6BC6 /* TempusRomanum */,
96A09A3C22AA0F3A00FE6BC6 /* Products */,
);
sourceTree = "<group>";
};
96A09A3C22AA0F3A00FE6BC6 /* Products */ = {
isa = PBXGroup;
children = (
96A09A3B22AA0F3A00FE6BC6 /* TempusRomanum.app */,
);
name = Products;
sourceTree = "<group>";
};
96A09A3D22AA0F3A00FE6BC6 /* TempusRomanum */ = {
isa = PBXGroup;
children = (
96A09A3E22AA0F3A00FE6BC6 /* AppDelegate.swift */,
96A09A4422AA0F3D00FE6BC6 /* Assets.xcassets */,
96A09A7022AA11D600FE6BC6 /* ClockView.swift */,
96A09A6E22AA110600FE6BC6 /* Home.swift */,
96A09A4C22AA0F3D00FE6BC6 /* Info.plist */,
96A09A4922AA0F3D00FE6BC6 /* LaunchScreen.storyboard */,
96A09A4622AA0F3D00FE6BC6 /* Preview Content */,
96A09A4022AA0F3A00FE6BC6 /* SceneDelegate.swift */,
);
path = TempusRomanum;
sourceTree = "<group>";
};
96A09A4622AA0F3D00FE6BC6 /* Preview Content */ = {
isa = PBXGroup;
children = (
96A09A4722AA0F3D00FE6BC6 /* Preview Assets.xcassets */,
);
path = "Preview Content";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
96A09A3A22AA0F3A00FE6BC6 /* TempusRomanum */ = {
isa = PBXNativeTarget;
buildConfigurationList = 96A09A6522AA0F3E00FE6BC6 /* Build configuration list for PBXNativeTarget "TempusRomanum" */;
buildPhases = (
96A09A3722AA0F3A00FE6BC6 /* Sources */,
96A09A3822AA0F3A00FE6BC6 /* Frameworks */,
96A09A3922AA0F3A00FE6BC6 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = TempusRomanum;
productName = TempusRomanum;
productReference = 96A09A3B22AA0F3A00FE6BC6 /* TempusRomanum.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
96A09A3322AA0F3A00FE6BC6 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1100;
LastUpgradeCheck = 1100;
ORGANIZATIONNAME = "Poikile Creations";
TargetAttributes = {
96A09A3A22AA0F3A00FE6BC6 = {
CreatedOnToolsVersion = 11.0;
};
};
};
buildConfigurationList = 96A09A3622AA0F3A00FE6BC6 /* Build configuration list for PBXProject "TempusRomanum" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 96A09A3222AA0F3A00FE6BC6;
productRefGroup = 96A09A3C22AA0F3A00FE6BC6 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
96A09A3A22AA0F3A00FE6BC6 /* TempusRomanum */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
96A09A3922AA0F3A00FE6BC6 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
96A09A4B22AA0F3D00FE6BC6 /* LaunchScreen.storyboard in Resources */,
96A09A4822AA0F3D00FE6BC6 /* Preview Assets.xcassets in Resources */,
96A09A4522AA0F3D00FE6BC6 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
96A09A3722AA0F3A00FE6BC6 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
96A09A3F22AA0F3A00FE6BC6 /* AppDelegate.swift in Sources */,
96A09A6F22AA110600FE6BC6 /* Home.swift in Sources */,
96A09A7122AA11D600FE6BC6 /* ClockView.swift in Sources */,
96A09A4122AA0F3A00FE6BC6 /* SceneDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
96A09A4922AA0F3D00FE6BC6 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
96A09A4A22AA0F3D00FE6BC6 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
96A09A6322AA0F3E00FE6BC6 /* 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;
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 = 13.0;
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;
};
96A09A6422AA0F3E00FE6BC6 /* 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;
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 = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
96A09A6622AA0F3E00FE6BC6 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "TempusRomanum/Preview\\ Content";
DEVELOPMENT_TEAM = 3MY7LL9G36;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = TempusRomanum/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = org.poikile.TempusRomanum;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
96A09A6722AA0F3E00FE6BC6 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "TempusRomanum/Preview\\ Content";
DEVELOPMENT_TEAM = 3MY7LL9G36;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = TempusRomanum/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = org.poikile.TempusRomanum;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
96A09A3622AA0F3A00FE6BC6 /* Build configuration list for PBXProject "TempusRomanum" */ = {
isa = XCConfigurationList;
buildConfigurations = (
96A09A6322AA0F3E00FE6BC6 /* Debug */,
96A09A6422AA0F3E00FE6BC6 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
96A09A6522AA0F3E00FE6BC6 /* Build configuration list for PBXNativeTarget "TempusRomanum" */ = {
isa = XCConfigurationList;
buildConfigurations = (
96A09A6622AA0F3E00FE6BC6 /* Debug */,
96A09A6722AA0F3E00FE6BC6 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 96A09A3322AA0F3A00FE6BC6 /* Project object */;
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:TempusRomanum.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -0,0 +1,8 @@
<?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>

View File

@@ -0,0 +1,35 @@
// Copyright © 2019 Poikile Creations. All rights reserved.
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}

View File

@@ -0,0 +1,98 @@
{
"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"
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -0,0 +1,25 @@
<?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" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<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>

View File

@@ -0,0 +1,55 @@
// Copyright © 2019 Poikile Creations. All rights reserved.
import SwiftUI
struct ClockView : View {
@State var showMilitaryTime = false
private var dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.timeStyle = .short
return formatter
}()
private var militaryDateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "HH:MM"
return formatter
}()
private var timeString: String {
if showMilitaryTime {
return militaryDateFormatter.string(from: Date())
} else {
return dateFormatter.string(from: Date())
}
}
var body: some View {
VStack {
Button(action: {
self.showMilitaryTime.toggle()
}) {
Text(self.timeString)
.font(.headline)
}
//
// Text("quinta hora noctis")
// .font(.subheadline)
// .italic()
// .padding(.top, 10)
}
}
}
#if DEBUG
struct Clock_Previews : PreviewProvider {
static var previews: some View {
ClockView()
}
}
#endif

View File

@@ -0,0 +1,19 @@
// Copyright © 2019 Poikile Creations. All rights reserved.
import SwiftUI
struct Home : View {
var body: some View {
VStack {
Text("Hello World")
}
}
}
#if DEBUG
struct Home_Previews : PreviewProvider {
static var previews: some View {
Home()
}
}
#endif

View File

@@ -0,0 +1,62 @@
<?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>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>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
</dict>
</array>
</dict>
</dict>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</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>
</dict>
</plist>

View File

@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -0,0 +1,53 @@
// Copyright © 2019 Poikile Creations. All rights reserved.
import UIKit
import SwiftUI
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
// Use a UIHostingController as window root view controller
let window = UIWindow(frame: UIScreen.main.bounds)
window.rootViewController = UIHostingController(rootView: Home())
self.window = window
window.makeKeyAndVisible()
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
}
}

View File

@@ -0,0 +1,538 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
8D49A1F722A8839D002D1C10 /* VideoRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D49A1F622A8839D002D1C10 /* VideoRow.swift */; };
8DC3392C22A89A7D00EDE8CF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8DC3392A22A89A7D00EDE8CF /* Assets.xcassets */; };
8DC3393122A8A14800EDE8CF /* UserData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DC3393022A8A14800EDE8CF /* UserData.swift */; };
B83D3F7B22A8529B000A9E72 /* PlayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B83D3F7A22A8529B000A9E72 /* PlayerViewController.swift */; };
B83D3F7D22A855C8000A9E72 /* Video.swift in Sources */ = {isa = PBXBuildFile; fileRef = B83D3F7C22A855C8000A9E72 /* Video.swift */; };
B8C3352422A83894003AD9B4 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8C3352322A83894003AD9B4 /* AppDelegate.swift */; };
B8C3352622A83894003AD9B4 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8C3352522A83894003AD9B4 /* SceneDelegate.swift */; };
B8C3352822A83894003AD9B4 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8C3352722A83894003AD9B4 /* MainView.swift */; };
B8C3352D22A83897003AD9B4 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B8C3352C22A83897003AD9B4 /* Preview Assets.xcassets */; };
B8C3353022A83897003AD9B4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B8C3352E22A83897003AD9B4 /* LaunchScreen.storyboard */; };
B8C3353B22A83898003AD9B4 /* WWDCPlayerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8C3353A22A83898003AD9B4 /* WWDCPlayerTests.swift */; };
B8E926AD22A8E22A009D3FF1 /* WeekDay.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8E926AC22A8E22A009D3FF1 /* WeekDay.swift */; };
B8E926AF22A8E242009D3FF1 /* Platform.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8E926AE22A8E242009D3FF1 /* Platform.swift */; };
B8E926B422A9CD69009D3FF1 /* WWDCPlayerTests.xctest in Resources */ = {isa = PBXBuildFile; fileRef = B8C3353622A83897003AD9B4 /* WWDCPlayerTests.xctest */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
B8C3353722A83897003AD9B4 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = B8C3351822A83894003AD9B4 /* Project object */;
proxyType = 1;
remoteGlobalIDString = B8C3351F22A83894003AD9B4;
remoteInfo = SwiftUISample;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
8D49A1F622A8839D002D1C10 /* VideoRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = VideoRow.swift; path = ../VideoRow.swift; sourceTree = "<group>"; };
8DC3392A22A89A7D00EDE8CF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
8DC3392B22A89A7D00EDE8CF /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
8DC3393022A8A14800EDE8CF /* UserData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserData.swift; sourceTree = "<group>"; };
B83D3F7A22A8529B000A9E72 /* PlayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PlayerViewController.swift; path = ../PlayerViewController.swift; sourceTree = "<group>"; };
B83D3F7C22A855C8000A9E72 /* Video.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Video.swift; sourceTree = "<group>"; };
B8C3352022A83894003AD9B4 /* WWDCPlayer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WWDCPlayer.app; sourceTree = BUILT_PRODUCTS_DIR; };
B8C3352322A83894003AD9B4 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
B8C3352522A83894003AD9B4 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
B8C3352722A83894003AD9B4 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MainView.swift; path = ../MainView.swift; sourceTree = "<group>"; };
B8C3352C22A83897003AD9B4 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
B8C3352F22A83897003AD9B4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
B8C3353622A83897003AD9B4 /* WWDCPlayerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WWDCPlayerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
B8C3353A22A83898003AD9B4 /* WWDCPlayerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WWDCPlayerTests.swift; sourceTree = "<group>"; };
B8C3353C22A83898003AD9B4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
B8E926AC22A8E22A009D3FF1 /* WeekDay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeekDay.swift; sourceTree = "<group>"; };
B8E926AE22A8E242009D3FF1 /* Platform.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Platform.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
B8C3351D22A83894003AD9B4 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
B8C3353322A83897003AD9B4 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
8D7DEE8B22A8950D005D6A10 /* Delegates */ = {
isa = PBXGroup;
children = (
B8C3352322A83894003AD9B4 /* AppDelegate.swift */,
B8C3352522A83894003AD9B4 /* SceneDelegate.swift */,
);
path = Delegates;
sourceTree = "<group>";
};
8DC3392922A89A7D00EDE8CF /* Supporting Files */ = {
isa = PBXGroup;
children = (
8DC3392A22A89A7D00EDE8CF /* Assets.xcassets */,
8DC3392B22A89A7D00EDE8CF /* Info.plist */,
);
path = "Supporting Files";
sourceTree = "<group>";
};
B8C3351722A83894003AD9B4 = {
isa = PBXGroup;
children = (
B8C3352222A83894003AD9B4 /* WWDCPlayer */,
B8C3353922A83898003AD9B4 /* WWDCPlayerTests */,
B8C3352122A83894003AD9B4 /* Products */,
);
sourceTree = "<group>";
};
B8C3352122A83894003AD9B4 /* Products */ = {
isa = PBXGroup;
children = (
B8C3352022A83894003AD9B4 /* WWDCPlayer.app */,
B8C3353622A83897003AD9B4 /* WWDCPlayerTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
B8C3352222A83894003AD9B4 /* WWDCPlayer */ = {
isa = PBXGroup;
children = (
B8C3352E22A83897003AD9B4 /* LaunchScreen.storyboard */,
8D7DEE8B22A8950D005D6A10 /* Delegates */,
B8C67D6522A8D09500C0B63F /* Model */,
B8E926B322A9CCAD009D3FF1 /* View */,
B8E926B022A8E24D009D3FF1 /* Enum */,
8DC3392922A89A7D00EDE8CF /* Supporting Files */,
B8C3352B22A83897003AD9B4 /* Preview Content */,
);
path = WWDCPlayer;
sourceTree = "<group>";
};
B8C3352B22A83897003AD9B4 /* Preview Content */ = {
isa = PBXGroup;
children = (
B8C3352C22A83897003AD9B4 /* Preview Assets.xcassets */,
);
path = "Preview Content";
sourceTree = "<group>";
};
B8C3353922A83898003AD9B4 /* WWDCPlayerTests */ = {
isa = PBXGroup;
children = (
B8C3353A22A83898003AD9B4 /* WWDCPlayerTests.swift */,
B8C3353C22A83898003AD9B4 /* Info.plist */,
);
path = WWDCPlayerTests;
sourceTree = "<group>";
};
B8C67D6522A8D09500C0B63F /* Model */ = {
isa = PBXGroup;
children = (
B83D3F7C22A855C8000A9E72 /* Video.swift */,
8DC3393022A8A14800EDE8CF /* UserData.swift */,
);
path = Model;
sourceTree = "<group>";
};
B8E926B022A8E24D009D3FF1 /* Enum */ = {
isa = PBXGroup;
children = (
B8E926AC22A8E22A009D3FF1 /* WeekDay.swift */,
B8E926AE22A8E242009D3FF1 /* Platform.swift */,
);
path = Enum;
sourceTree = "<group>";
};
B8E926B322A9CCAD009D3FF1 /* View */ = {
isa = PBXGroup;
children = (
B8C3352722A83894003AD9B4 /* MainView.swift */,
8D49A1F622A8839D002D1C10 /* VideoRow.swift */,
B83D3F7A22A8529B000A9E72 /* PlayerViewController.swift */,
);
path = View;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
B8C3351F22A83894003AD9B4 /* WWDCPlayer */ = {
isa = PBXNativeTarget;
buildConfigurationList = B8C3353F22A83898003AD9B4 /* Build configuration list for PBXNativeTarget "WWDCPlayer" */;
buildPhases = (
B8C3351C22A83894003AD9B4 /* Sources */,
B8C3351D22A83894003AD9B4 /* Frameworks */,
B8C3351E22A83894003AD9B4 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = WWDCPlayer;
productName = SwiftUISample;
productReference = B8C3352022A83894003AD9B4 /* WWDCPlayer.app */;
productType = "com.apple.product-type.application";
};
B8C3353522A83897003AD9B4 /* WWDCPlayerTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = B8C3354222A83898003AD9B4 /* Build configuration list for PBXNativeTarget "WWDCPlayerTests" */;
buildPhases = (
B8C3353222A83897003AD9B4 /* Sources */,
B8C3353322A83897003AD9B4 /* Frameworks */,
B8C3353422A83897003AD9B4 /* Resources */,
);
buildRules = (
);
dependencies = (
B8C3353822A83897003AD9B4 /* PBXTargetDependency */,
);
name = WWDCPlayerTests;
productName = SwiftUISampleTests;
productReference = B8C3353622A83897003AD9B4 /* WWDCPlayerTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
B8C3351822A83894003AD9B4 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1100;
LastUpgradeCheck = 1100;
ORGANIZATIONNAME = daybreak;
TargetAttributes = {
B8C3351F22A83894003AD9B4 = {
CreatedOnToolsVersion = 11.0;
};
B8C3353522A83897003AD9B4 = {
CreatedOnToolsVersion = 11.0;
TestTargetID = B8C3351F22A83894003AD9B4;
};
};
};
buildConfigurationList = B8C3351B22A83894003AD9B4 /* Build configuration list for PBXProject "WWDCPlayer" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = B8C3351722A83894003AD9B4;
productRefGroup = B8C3352122A83894003AD9B4 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
B8C3351F22A83894003AD9B4 /* WWDCPlayer */,
B8C3353522A83897003AD9B4 /* WWDCPlayerTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
B8C3351E22A83894003AD9B4 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B8C3353022A83897003AD9B4 /* LaunchScreen.storyboard in Resources */,
8DC3392C22A89A7D00EDE8CF /* Assets.xcassets in Resources */,
B8C3352D22A83897003AD9B4 /* Preview Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
B8C3353422A83897003AD9B4 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B8E926B422A9CD69009D3FF1 /* WWDCPlayerTests.xctest in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
B8C3351C22A83894003AD9B4 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B8C3352422A83894003AD9B4 /* AppDelegate.swift in Sources */,
B8C3352622A83894003AD9B4 /* SceneDelegate.swift in Sources */,
B8E926AD22A8E22A009D3FF1 /* WeekDay.swift in Sources */,
B8C3352822A83894003AD9B4 /* MainView.swift in Sources */,
8DC3393122A8A14800EDE8CF /* UserData.swift in Sources */,
B8E926AF22A8E242009D3FF1 /* Platform.swift in Sources */,
B83D3F7B22A8529B000A9E72 /* PlayerViewController.swift in Sources */,
8D49A1F722A8839D002D1C10 /* VideoRow.swift in Sources */,
B83D3F7D22A855C8000A9E72 /* Video.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
B8C3353222A83897003AD9B4 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B8C3353B22A83898003AD9B4 /* WWDCPlayerTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
B8C3353822A83897003AD9B4 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = B8C3351F22A83894003AD9B4 /* WWDCPlayer */;
targetProxy = B8C3353722A83897003AD9B4 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
B8C3352E22A83897003AD9B4 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
B8C3352F22A83897003AD9B4 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
B8C3353D22A83898003AD9B4 /* 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;
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 = 13.0;
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;
};
B8C3353E22A83898003AD9B4 /* 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;
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 = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
B8C3354022A83898003AD9B4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "WWDCPlayer/Preview\\ Content";
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = "$(SRCROOT)/WWDCPlayer/Supporting Files/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.daybreak.WWDCPlayer;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
B8C3354122A83898003AD9B4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "WWDCPlayer/Preview\\ Content";
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = "$(SRCROOT)/WWDCPlayer/Supporting Files/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.daybreak.WWDCPlayer;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
B8C3354322A83898003AD9B4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
INFOPLIST_FILE = WWDCPlayerTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.daybreak.WWDCPlayerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WWDCPlayer.app/WWDCPlayer";
};
name = Debug;
};
B8C3354422A83898003AD9B4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
INFOPLIST_FILE = WWDCPlayerTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.daybreak.WWDCPlayerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WWDCPlayer.app/WWDCPlayer";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
B8C3351B22A83894003AD9B4 /* Build configuration list for PBXProject "WWDCPlayer" */ = {
isa = XCConfigurationList;
buildConfigurations = (
B8C3353D22A83898003AD9B4 /* Debug */,
B8C3353E22A83898003AD9B4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
B8C3353F22A83898003AD9B4 /* Build configuration list for PBXNativeTarget "WWDCPlayer" */ = {
isa = XCConfigurationList;
buildConfigurations = (
B8C3354022A83898003AD9B4 /* Debug */,
B8C3354122A83898003AD9B4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
B8C3354222A83898003AD9B4 /* Build configuration list for PBXNativeTarget "WWDCPlayerTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
B8C3354322A83898003AD9B4 /* Debug */,
B8C3354422A83898003AD9B4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = B8C3351822A83894003AD9B4 /* Project object */;
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:/Users/yunminseob/Desktop/project/SwiftUISample/WWDCPlayer.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -0,0 +1,8 @@
<?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>

View File

@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1100"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B8C3351F22A83894003AD9B4"
BuildableName = "WWDCPlayer.app"
BlueprintName = "WWDCPlayer"
ReferencedContainer = "container:WWDCPlayer.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B8C3353522A83897003AD9B4"
BuildableName = "WWDCPlayerTests.xctest"
BlueprintName = "WWDCPlayerTests"
ReferencedContainer = "container:WWDCPlayer.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B8C3351F22A83894003AD9B4"
BuildableName = "WWDCPlayer.app"
BlueprintName = "WWDCPlayer"
ReferencedContainer = "container:WWDCPlayer.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B8C3351F22A83894003AD9B4"
BuildableName = "WWDCPlayer.app"
BlueprintName = "WWDCPlayer"
ReferencedContainer = "container:WWDCPlayer.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -0,0 +1,202 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14810.11" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14766.13"/>
<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="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bIb-4l-Tc8">
<rect key="frame" x="0.0" y="0.0" width="414" height="148.5"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vXv-ip-ToS">
<rect key="frame" x="20" y="88.5" width="240" height="50"/>
<color key="backgroundColor" white="0.0" alpha="0.050000000000000003" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="width" constant="240" id="Eeq-fp-M98"/>
<constraint firstAttribute="height" constant="50" id="dtg-df-t1v"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<constraints>
<constraint firstAttribute="height" constant="148.5" id="U7r-9E-9Ba"/>
<constraint firstItem="vXv-ip-ToS" firstAttribute="leading" secondItem="bIb-4l-Tc8" secondAttribute="leading" constant="20" id="ahN-Fw-cbL"/>
<constraint firstAttribute="bottom" secondItem="vXv-ip-ToS" secondAttribute="bottom" constant="10" id="n5H-zz-Gec"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="4vA-UI-tEX">
<rect key="frame" x="0.0" y="148.5" width="414" height="333"/>
<color key="backgroundColor" white="0.0" alpha="0.050000000000000003" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="333" id="cd6-r1-yua"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="GsT-jT-xfX" userLabel="ListView">
<rect key="frame" x="0.0" y="481.5" width="414" height="414.5"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="U3F-Gs-4WC" userLabel="View1">
<rect key="frame" x="0.0" y="0.0" width="414" height="70"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="llU-zJ-ZGF">
<rect key="frame" x="20" y="20" width="240" height="30"/>
<color key="backgroundColor" white="0.0" alpha="0.050000000000000003" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="width" constant="240" id="Prq-jN-UNr"/>
<constraint firstAttribute="height" constant="30" id="mTz-I1-yCy"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="KXh-lq-RRl">
<rect key="frame" x="20" y="69" width="394" height="1"/>
<color key="backgroundColor" white="0.0" alpha="0.050000000000000003" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="UwK-Lj-ODc"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="KXh-lq-RRl" secondAttribute="bottom" id="Cz4-ex-BVk"/>
<constraint firstItem="KXh-lq-RRl" firstAttribute="leading" secondItem="U3F-Gs-4WC" secondAttribute="leading" constant="20" id="auY-KJ-TBW"/>
<constraint firstItem="llU-zJ-ZGF" firstAttribute="centerY" secondItem="U3F-Gs-4WC" secondAttribute="centerY" id="bGN-6c-sXj"/>
<constraint firstAttribute="height" constant="70" id="mte-XG-qi8"/>
<constraint firstItem="llU-zJ-ZGF" firstAttribute="leading" secondItem="U3F-Gs-4WC" secondAttribute="leading" constant="20" id="omr-V7-UUU"/>
<constraint firstAttribute="trailing" secondItem="KXh-lq-RRl" secondAttribute="trailing" id="ymr-aD-0rE"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="PaP-r5-oc8" userLabel="View2">
<rect key="frame" x="0.0" y="70" width="414" height="70"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bkD-UM-CTc">
<rect key="frame" x="20" y="20" width="240" height="30"/>
<color key="backgroundColor" white="0.0" alpha="0.050000000000000003" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="30" id="4fl-eT-kkY"/>
<constraint firstAttribute="width" constant="240" id="vYt-qb-jFQ"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="uOO-oy-uv3">
<rect key="frame" x="20" y="69" width="394" height="1"/>
<color key="backgroundColor" white="0.0" alpha="0.050000000000000003" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="YtO-aa-P42"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<constraints>
<constraint firstItem="bkD-UM-CTc" firstAttribute="leading" secondItem="PaP-r5-oc8" secondAttribute="leading" constant="20" id="9mr-PQ-He5"/>
<constraint firstAttribute="height" constant="70" id="Wtd-Y5-4gQ"/>
<constraint firstAttribute="trailing" secondItem="uOO-oy-uv3" secondAttribute="trailing" id="Xik-tq-ryg"/>
<constraint firstAttribute="bottom" secondItem="uOO-oy-uv3" secondAttribute="bottom" id="ceH-sL-E04"/>
<constraint firstItem="bkD-UM-CTc" firstAttribute="centerY" secondItem="PaP-r5-oc8" secondAttribute="centerY" id="o9J-jd-0x0"/>
<constraint firstItem="uOO-oy-uv3" firstAttribute="leading" secondItem="PaP-r5-oc8" secondAttribute="leading" constant="20" id="pJM-ER-Pgt"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="UEU-oh-ntl" userLabel="View3">
<rect key="frame" x="0.0" y="140" width="414" height="70"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Yft-lI-14Q">
<rect key="frame" x="20" y="20" width="240" height="30"/>
<color key="backgroundColor" white="0.0" alpha="0.050000000000000003" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="width" constant="240" id="7B4-y2-Cm3"/>
<constraint firstAttribute="height" constant="30" id="bwH-0m-DbC"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qXs-S4-cuJ">
<rect key="frame" x="20" y="69" width="394" height="1"/>
<color key="backgroundColor" white="0.0" alpha="0.050000000000000003" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="sEQ-oo-Orp"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<constraints>
<constraint firstItem="Yft-lI-14Q" firstAttribute="centerY" secondItem="UEU-oh-ntl" secondAttribute="centerY" id="5CQ-AR-BrK"/>
<constraint firstItem="Yft-lI-14Q" firstAttribute="leading" secondItem="UEU-oh-ntl" secondAttribute="leading" constant="20" id="9VU-Dz-FM4"/>
<constraint firstAttribute="trailing" secondItem="qXs-S4-cuJ" secondAttribute="trailing" id="KhX-xm-3JS"/>
<constraint firstAttribute="height" constant="70" id="OS7-VI-Ea0"/>
<constraint firstItem="qXs-S4-cuJ" firstAttribute="leading" secondItem="UEU-oh-ntl" secondAttribute="leading" constant="20" id="klF-H2-vEu"/>
<constraint firstAttribute="bottom" secondItem="qXs-S4-cuJ" secondAttribute="bottom" id="vUL-MO-I14"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ybg-ga-e6U" userLabel="View4">
<rect key="frame" x="0.0" y="210" width="414" height="70"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="eUZ-Ys-y3a">
<rect key="frame" x="20" y="20" width="240" height="30"/>
<color key="backgroundColor" white="0.0" alpha="0.050000000000000003" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="30" id="I9x-Np-M1x"/>
<constraint firstAttribute="width" constant="240" id="ueQ-zp-gsO"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="RDL-Rf-c2c">
<rect key="frame" x="20" y="69" width="394" height="1"/>
<color key="backgroundColor" white="0.0" alpha="0.050000000000000003" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="pZI-sZ-Quc"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<constraints>
<constraint firstItem="eUZ-Ys-y3a" firstAttribute="leading" secondItem="ybg-ga-e6U" secondAttribute="leading" constant="20" id="Wu9-SV-apz"/>
<constraint firstAttribute="bottom" secondItem="RDL-Rf-c2c" secondAttribute="bottom" id="XPi-Yn-d7K"/>
<constraint firstAttribute="height" constant="70" id="bMV-Tx-P2x"/>
<constraint firstAttribute="trailing" secondItem="RDL-Rf-c2c" secondAttribute="trailing" id="bu8-Bs-K9g"/>
<constraint firstItem="eUZ-Ys-y3a" firstAttribute="centerY" secondItem="ybg-ga-e6U" secondAttribute="centerY" id="e2v-Ha-rZq"/>
<constraint firstItem="RDL-Rf-c2c" firstAttribute="leading" secondItem="ybg-ga-e6U" secondAttribute="leading" constant="20" id="ge2-CZ-xmC"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<constraints>
<constraint firstItem="UEU-oh-ntl" firstAttribute="leading" secondItem="GsT-jT-xfX" secondAttribute="leading" id="3Eg-Q7-dEY"/>
<constraint firstAttribute="trailing" secondItem="ybg-ga-e6U" secondAttribute="trailing" id="3hK-Gf-Apu"/>
<constraint firstItem="ybg-ga-e6U" firstAttribute="top" secondItem="UEU-oh-ntl" secondAttribute="bottom" id="5Y4-oM-vj0"/>
<constraint firstItem="PaP-r5-oc8" firstAttribute="leading" secondItem="GsT-jT-xfX" secondAttribute="leading" id="MYo-q1-LG4"/>
<constraint firstAttribute="trailing" secondItem="PaP-r5-oc8" secondAttribute="trailing" id="P5v-b7-ZZa"/>
<constraint firstItem="PaP-r5-oc8" firstAttribute="bottom" secondItem="UEU-oh-ntl" secondAttribute="top" id="hY5-j4-d7I"/>
<constraint firstAttribute="trailing" secondItem="UEU-oh-ntl" secondAttribute="trailing" id="miW-fC-i8X"/>
<constraint firstItem="PaP-r5-oc8" firstAttribute="top" secondItem="U3F-Gs-4WC" secondAttribute="bottom" id="mpc-jM-n7U"/>
<constraint firstItem="U3F-Gs-4WC" firstAttribute="leading" secondItem="GsT-jT-xfX" secondAttribute="leading" id="rx1-fn-tNn"/>
<constraint firstItem="ybg-ga-e6U" firstAttribute="leading" secondItem="GsT-jT-xfX" secondAttribute="leading" id="t7Q-xh-1tU"/>
<constraint firstItem="U3F-Gs-4WC" firstAttribute="top" secondItem="GsT-jT-xfX" secondAttribute="top" id="vIV-OC-hIS"/>
<constraint firstAttribute="trailing" secondItem="U3F-Gs-4WC" secondAttribute="trailing" id="xEn-KM-9pi"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<constraints>
<constraint firstItem="bIb-4l-Tc8" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="2o4-bN-7xE"/>
<constraint firstItem="4vA-UI-tEX" firstAttribute="trailing" secondItem="bIb-4l-Tc8" secondAttribute="trailing" id="498-2l-nA8"/>
<constraint firstItem="GsT-jT-xfX" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="7XC-hr-0bi"/>
<constraint firstItem="GsT-jT-xfX" firstAttribute="top" secondItem="4vA-UI-tEX" secondAttribute="bottom" id="C1g-Ij-U4O"/>
<constraint firstItem="4vA-UI-tEX" firstAttribute="leading" secondItem="bIb-4l-Tc8" secondAttribute="leading" id="FV3-tt-eNh"/>
<constraint firstItem="bIb-4l-Tc8" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="Q8v-mw-JnD"/>
<constraint firstAttribute="bottom" secondItem="GsT-jT-xfX" secondAttribute="bottom" id="agc-V4-zHC"/>
<constraint firstAttribute="trailing" secondItem="GsT-jT-xfX" secondAttribute="trailing" id="dDB-Ay-EYy"/>
<constraint firstItem="4vA-UI-tEX" firstAttribute="top" secondItem="bIb-4l-Tc8" secondAttribute="bottom" id="mRa-be-DO1"/>
<constraint firstAttribute="trailing" secondItem="bIb-4l-Tc8" secondAttribute="trailing" id="sB5-am-1KZ"/>
</constraints>
<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>

View File

@@ -0,0 +1,41 @@
//
// AppDelegate.swift
// WWDCPlayer
//
// Created by ms on 2019/06/05.
// Copyright © 2019 daybreak. All rights reserved.
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}

View File

@@ -0,0 +1,60 @@
//
// SceneDelegate.swift
// WWDCPlayer
//
// Created by ms on 2019/06/05.
// Copyright © 2019 daybreak. All rights reserved.
//
import UIKit
import SwiftUI
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
// Use a UIHostingController as window root view controller
let window = UIWindow(frame: UIScreen.main.bounds)
window.rootViewController = UIHostingController(rootView: MainView()
.environmentObject(UserData()))
self.window = window
window.makeKeyAndVisible()
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
}
}

View File

@@ -0,0 +1,15 @@
//
// Platform.swift
// WWDCPlayer
//
// Created by sohee on 2019/06/05.
// Copyright © 2019 daybreak. All rights reserved.
//
import Foundation
enum Platform: String, CaseIterable {
case iOS, macOS, tvOS, watchOS
}
let allPlatforms = Platform.allCases

View File

@@ -0,0 +1,23 @@
//
// WeekDay.swift
// WWDCPlayer
//
// Created by ms on 2019/06/05.
// Copyright © 2019 daybreak. All rights reserved.
//
import Foundation
import SwiftUI
enum WeekDay: String, CaseIterable, Identifiable {
var id: String {
return self.rawValue
}
case monday
case tuesday
case wednesday
case thursday
case friday
}
let allWeekDays = WeekDay.allCases

View File

@@ -0,0 +1,72 @@
//
// MainView.swift
// WWDCPlayer
//
// Created by ms on 2019/06/05.
// Copyright © 2019 daybreak. All rights reserved.
//
import SwiftUI
import AVFoundation
struct MainView: View {
@EnvironmentObject var userData: UserData
let player = AVPlayer()
var body: some View {
NavigationView {
VStack {
ZStack(alignment: .bottom) {
PlayerViewController(video: $userData.currentVideo)
}
FavoriteToggleView()
VideoListView()
}
.navigationBarTitle(Text(userData.currentVideo.title))
}
}
}
#if DEBUG
struct MainView_Previews : PreviewProvider {
static var previews: some View {
MainView()
.environmentObject(UserData())
}
}
#endif
struct FavoriteToggleView: View {
@EnvironmentObject var userData: UserData
var body: some View {
Toggle(isOn: $userData.showFavoriteOnly) {
Text("Favorite Only")
.foregroundColor(Color.yellow)
}
.padding([.leading, .trailing], 20)
}
}
struct VideoListView : View {
@EnvironmentObject var userData: UserData
var body: some View {
List {
ForEach(allWeekDays) { day in
Section(header: Text(day.rawValue.uppercased()).fontWeight(.bold)) {
ForEach(self.userData.videos.filter { $0.weekDay == day }) { video in
if !self.userData.showFavoriteOnly || video.isFavorite {
VideoRow(video: video)
}
}
}
}
}.listStyle(.grouped)
}
}

View File

@@ -0,0 +1,31 @@
//
// UserData.swift
// WWDCPlayer
//
// Created by sohee on 2019/06/06.
// Copyright © 2019 daybreak. All rights reserved.
//
import SwiftUI
import Combine
final class UserData: BindableObject {
let didChange = PassthroughSubject<UserData, Never>()
var showFavoriteOnly = false {
didSet {
didChange.send(self)
}
}
var videos = videoList {
didSet {
didChange.send(self)
}
}
var currentVideo = videoList[0] {
didSet {
didChange.send(self)
}
}
}

View File

@@ -0,0 +1,35 @@
//
// Video.swift
// WWDCPlayer
//
// Created by ms on 2019/06/05.
// Copyright © 2019 daybreak. All rights reserved.
//
import Foundation
import SwiftUI
struct Video: Identifiable, Equatable {
var id: Int
var title: String
var url: String
var weekDay: WeekDay
var platforms: [Platform]
var isFavorite = false
var platformString: String {
return platforms.map { $0.rawValue }.joined(separator: ", ")
}
static func == (lhs: Video, rhs: Video) -> Bool {
return lhs.id == rhs.id
}
}
let videoList = [
Video(id: 101, title: "Keynote🤖", url: "https://p-events-delivery.akamaized.net/3004qzusahnbjppuwydgjzsdyzsippar/m3u8/hls_vod_mvp.m3u8", weekDay: .monday, platforms: allPlatforms),
Video(id: 103, title: "Platforms State of the Union🛠", url: "https://devstreaming-cdn.apple.com/videos/wwdc/2019/103bax22h2udxu0n/103/hls_vod_mvp.m3u8", weekDay: .monday, platforms: allPlatforms),
Video(id: 104, title: "Apple Design Awards🏆", url: "https://devstreaming-cdn.apple.com/videos/wwdc/2019/104d6zyhb21vki/104/hls_vod_mvp.m3u8", weekDay: .monday, platforms: allPlatforms),
Video(id: 204, title: "Introducing SwiftUI: Building Your First App", url: "https://devstreaming-cdn.apple.com/videos/wwdc/2019/204isgnpbqud244/204/hls_vod_mvp.m3u8", weekDay: .tuesday, platforms: allPlatforms),
Video(id: 214, title: "Implementing Dark Mode on iOS", url: "https://devstreaming-cdn.apple.com/videos/wwdc/2019/214iqtpuhih53fw2/214/hls_vod_mvp.m3u8", weekDay: .wednesday, platforms: [.iOS])
]

View File

@@ -0,0 +1,37 @@
//
// PlayerViewController.swift
// WWDCPlayer
//
// Created by ms on 2019/06/05.
// Copyright © 2019 daybreak. All rights reserved.
//
import SwiftUI
import AVKit
struct PlayerViewController: UIViewControllerRepresentable {
@Binding var video: Video
private let player = AVPlayer()
func makeUIViewController(context: Context) -> AVPlayerViewController {
let playerVC = AVPlayerViewController()
playerVC.player = self.player
return playerVC
}
func updateUIViewController(_ uiViewController: AVPlayerViewController, context: Context) {
guard let url = URL(string: video.url) else { return }
resetPlayer(uiViewController)
let item = AVPlayerItem(url: url)
uiViewController.player?.replaceCurrentItem(with: item)
}
func resetPlayer(_ vc: AVPlayerViewController) {
vc.player?.pause()
vc.player?.replaceCurrentItem(with: nil)
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -0,0 +1,122 @@
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "ItunesArtwork@2x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1000 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Some files were not shown because too many files have changed in this diff Show More