Init
parent
13c6dd1979
commit
82e8dd991a
|
@ -0,0 +1,351 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
193322BA28BABE4C00ECECB0 /* ChatModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193322B928BABE4C00ECECB0 /* ChatModel.swift */; };
|
||||
193322BC28BAC60900ECECB0 /* Date+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193322BB28BAC60900ECECB0 /* Date+Helpers.swift */; };
|
||||
193322C028BAC92F00ECECB0 /* ChatsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193322BF28BAC92F00ECECB0 /* ChatsViewModel.swift */; };
|
||||
193322C228BACCDA00ECECB0 /* ChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193322C128BACCDA00ECECB0 /* ChatView.swift */; };
|
||||
C07D316878F6AA0353D447AC /* ChatRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C07D3D7C6B2D53FDE2D935E0 /* ChatRow.swift */; };
|
||||
C07D3754C665BEFBB6512D42 /* .gitignore in Resources */ = {isa = PBXBuildFile; fileRef = C07D3595FE6195CC1E0EF874 /* .gitignore */; };
|
||||
C07D39C9FDC07D92EA4484E8 /* TrainingApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C07D3FD47910198196A071C6 /* TrainingApp.swift */; };
|
||||
C07D3B52F9476D6CBBDA9F86 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C07D39E44D0D6D8CEE7B119B /* ContentView.swift */; };
|
||||
C07D3CE7CD14489A53B34593 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C07D3AC94044DC0078A9C96B /* Preview Assets.xcassets */; };
|
||||
C07D3EC1DF66197FCF10B04A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C07D323607E19080E00F500C /* Assets.xcassets */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
193322B928BABE4C00ECECB0 /* ChatModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatModel.swift; sourceTree = "<group>"; };
|
||||
193322BB28BAC60900ECECB0 /* Date+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date+Helpers.swift"; sourceTree = "<group>"; };
|
||||
193322BF28BAC92F00ECECB0 /* ChatsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatsViewModel.swift; sourceTree = "<group>"; };
|
||||
193322C128BACCDA00ECECB0 /* ChatView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatView.swift; sourceTree = "<group>"; };
|
||||
C07D306AC5D69BF90D6B7837 /* Training.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Training.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
C07D323607E19080E00F500C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
C07D3595FE6195CC1E0EF874 /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = file.gitignore; path = .gitignore; sourceTree = "<group>"; };
|
||||
C07D39E44D0D6D8CEE7B119B /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||
C07D3AC94044DC0078A9C96B /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
||||
C07D3D7C6B2D53FDE2D935E0 /* ChatRow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatRow.swift; sourceTree = "<group>"; };
|
||||
C07D3FD47910198196A071C6 /* TrainingApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrainingApp.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
C07D35D9F1DE858A42F9EA17 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
C07D31B1964ABAA1A810E3AF /* Training */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C07D323607E19080E00F500C /* Assets.xcassets */,
|
||||
C07D3D1BECC205B3E5399B3A /* Preview Content */,
|
||||
C07D3FD47910198196A071C6 /* TrainingApp.swift */,
|
||||
C07D39E44D0D6D8CEE7B119B /* ContentView.swift */,
|
||||
C07D3D7C6B2D53FDE2D935E0 /* ChatRow.swift */,
|
||||
193322B928BABE4C00ECECB0 /* ChatModel.swift */,
|
||||
193322BB28BAC60900ECECB0 /* Date+Helpers.swift */,
|
||||
193322BF28BAC92F00ECECB0 /* ChatsViewModel.swift */,
|
||||
193322C128BACCDA00ECECB0 /* ChatView.swift */,
|
||||
);
|
||||
path = Training;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C07D371AFE61FD792BFD1B66 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C07D306AC5D69BF90D6B7837 /* Training.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C07D39A49118DB20FD6FC2F6 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C07D371AFE61FD792BFD1B66 /* Products */,
|
||||
C07D31B1964ABAA1A810E3AF /* Training */,
|
||||
C07D3595FE6195CC1E0EF874 /* .gitignore */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C07D3D1BECC205B3E5399B3A /* Preview Content */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C07D3AC94044DC0078A9C96B /* Preview Assets.xcassets */,
|
||||
);
|
||||
path = "Preview Content";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
C07D358237A92B11CC514E20 /* Training */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = C07D3105791B837A22B25329 /* Build configuration list for PBXNativeTarget "Training" */;
|
||||
buildPhases = (
|
||||
C07D3E323FBC052ED49F708A /* Sources */,
|
||||
C07D35D9F1DE858A42F9EA17 /* Frameworks */,
|
||||
C07D3697D5A54CFD2B988BB1 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = Training;
|
||||
productName = Training;
|
||||
productReference = C07D306AC5D69BF90D6B7837 /* Training.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
C07D3850411372B23AADAF30 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
};
|
||||
buildConfigurationList = C07D319DD8CBD07A95D69AAC /* Build configuration list for PBXProject "Training" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
English,
|
||||
en,
|
||||
);
|
||||
mainGroup = C07D39A49118DB20FD6FC2F6;
|
||||
productRefGroup = C07D371AFE61FD792BFD1B66 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
C07D358237A92B11CC514E20 /* Training */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
C07D3697D5A54CFD2B988BB1 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
C07D3EC1DF66197FCF10B04A /* Assets.xcassets in Resources */,
|
||||
C07D3CE7CD14489A53B34593 /* Preview Assets.xcassets in Resources */,
|
||||
C07D3754C665BEFBB6512D42 /* .gitignore in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
C07D3E323FBC052ED49F708A /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
193322C028BAC92F00ECECB0 /* ChatsViewModel.swift in Sources */,
|
||||
C07D39C9FDC07D92EA4484E8 /* TrainingApp.swift in Sources */,
|
||||
C07D3B52F9476D6CBBDA9F86 /* ContentView.swift in Sources */,
|
||||
C07D316878F6AA0353D447AC /* ChatRow.swift in Sources */,
|
||||
193322C228BACCDA00ECECB0 /* ChatView.swift in Sources */,
|
||||
193322BA28BABE4C00ECECB0 /* ChatModel.swift in Sources */,
|
||||
193322BC28BAC60900ECECB0 /* Date+Helpers.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
C07D3289C94B96864CE471AD /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"Training/Preview Content\"";
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = mrtuxa.Training;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
C07D35A68F4E4FB5617ECC75 /* 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++17";
|
||||
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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
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 = 15.2;
|
||||
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;
|
||||
};
|
||||
C07D36637BD8CF8F50D1DF55 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"Training/Preview Content\"";
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = mrtuxa.Training;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
C07D3EBF265CF8C9E4BBA01B /* 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++17";
|
||||
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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
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 = 15.2;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
C07D3105791B837A22B25329 /* Build configuration list for PBXNativeTarget "Training" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
C07D3289C94B96864CE471AD /* Debug */,
|
||||
C07D36637BD8CF8F50D1DF55 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
C07D319DD8CBD07A95D69AAC /* Build configuration list for PBXProject "Training" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
C07D35A68F4E4FB5617ECC75 /* Debug */,
|
||||
C07D3EBF265CF8C9E4BBA01B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = C07D3850411372B23AADAF30 /* Project object */;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
|
@ -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>
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"colors": [
|
||||
{
|
||||
"idiom": "universal"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
{
|
||||
"images": [
|
||||
{
|
||||
"idiom": "iphone",
|
||||
"scale": "2x",
|
||||
"size": "20x20"
|
||||
},
|
||||
{
|
||||
"idiom": "iphone",
|
||||
"scale": "3x",
|
||||
"size": "20x20"
|
||||
},
|
||||
{
|
||||
"idiom": "iphone",
|
||||
"scale": "2x",
|
||||
"size": "29x29"
|
||||
},
|
||||
{
|
||||
"idiom": "iphone",
|
||||
"scale": "3x",
|
||||
"size": "29x29"
|
||||
},
|
||||
{
|
||||
"idiom": "iphone",
|
||||
"scale": "2x",
|
||||
"size": "40x40"
|
||||
},
|
||||
{
|
||||
"idiom": "iphone",
|
||||
"scale": "3x",
|
||||
"size": "40x40"
|
||||
},
|
||||
{
|
||||
"idiom": "iphone",
|
||||
"scale": "2x",
|
||||
"size": "60x60"
|
||||
},
|
||||
{
|
||||
"idiom": "iphone",
|
||||
"scale": "3x",
|
||||
"size": "60x60"
|
||||
},
|
||||
{
|
||||
"idiom": "ipad",
|
||||
"scale": "1x",
|
||||
"size": "20x20"
|
||||
},
|
||||
{
|
||||
"idiom": "ipad",
|
||||
"scale": "2x",
|
||||
"size": "20x20"
|
||||
},
|
||||
{
|
||||
"idiom": "ipad",
|
||||
"scale": "1x",
|
||||
"size": "29x29"
|
||||
},
|
||||
{
|
||||
"idiom": "ipad",
|
||||
"scale": "2x",
|
||||
"size": "29x29"
|
||||
},
|
||||
{
|
||||
"idiom": "ipad",
|
||||
"scale": "1x",
|
||||
"size": "40x40"
|
||||
},
|
||||
{
|
||||
"idiom": "ipad",
|
||||
"scale": "2x",
|
||||
"size": "40x40"
|
||||
},
|
||||
{
|
||||
"idiom": "ipad",
|
||||
"scale": "1x",
|
||||
"size": "76x76"
|
||||
},
|
||||
{
|
||||
"idiom": "ipad",
|
||||
"scale": "2x",
|
||||
"size": "76x76"
|
||||
},
|
||||
{
|
||||
"idiom": "ipad",
|
||||
"scale": "2x",
|
||||
"size": "83.5x83.5"
|
||||
},
|
||||
{
|
||||
"idiom": "ios-marketing",
|
||||
"scale": "1x",
|
||||
"size": "1024x1024"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"colors": [
|
||||
{
|
||||
"color": {
|
||||
"color-space": "srgb",
|
||||
"components": {
|
||||
"alpha": "1.000",
|
||||
"blue": "1.000",
|
||||
"green": "1.000",
|
||||
"red": "1.000"
|
||||
}
|
||||
},
|
||||
"idiom": "universal"
|
||||
},
|
||||
{
|
||||
"appearances": [
|
||||
{
|
||||
"appearance": "luminosity",
|
||||
"value": "dark"
|
||||
}
|
||||
],
|
||||
"color": {
|
||||
"color-space": "srgb",
|
||||
"components": {
|
||||
"alpha": "1.000",
|
||||
"blue": "1.000",
|
||||
"green": "1.000",
|
||||
"red": "1.000"
|
||||
}
|
||||
},
|
||||
"idiom": "universal"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"colors": [
|
||||
{
|
||||
"color": {
|
||||
"color-space": "srgb",
|
||||
"components": {
|
||||
"alpha": "1.000",
|
||||
"blue": "1.000",
|
||||
"green": "1.000",
|
||||
"red": "1.000"
|
||||
}
|
||||
},
|
||||
"idiom": "universal"
|
||||
},
|
||||
{
|
||||
"appearances": [
|
||||
{
|
||||
"appearance": "luminosity",
|
||||
"value": "dark"
|
||||
}
|
||||
],
|
||||
"color": {
|
||||
"color-space": "srgb",
|
||||
"components": {
|
||||
"alpha": "1.000",
|
||||
"blue": "1.000",
|
||||
"green": "1.000",
|
||||
"red": "1.000"
|
||||
}
|
||||
},
|
||||
"idiom": "universal"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"colors": [
|
||||
{
|
||||
"color": {
|
||||
"color-space": "srgb",
|
||||
"components": {
|
||||
"alpha": "1.000",
|
||||
"blue": "1.000",
|
||||
"green": "1.000",
|
||||
"red": "1.000"
|
||||
}
|
||||
},
|
||||
"idiom": "universal"
|
||||
},
|
||||
{
|
||||
"appearances": [
|
||||
{
|
||||
"appearance": "luminosity",
|
||||
"value": "dark"
|
||||
}
|
||||
],
|
||||
"color": {
|
||||
"color-space": "srgb",
|
||||
"components": {
|
||||
"alpha": "1.000",
|
||||
"blue": "1.000",
|
||||
"green": "1.000",
|
||||
"red": "1.000"
|
||||
}
|
||||
},
|
||||
"idiom": "universal"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"images": [
|
||||
{
|
||||
"filename": "Unbenannt-1.jpeg",
|
||||
"idiom": "universal",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "3x"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"images": [
|
||||
{
|
||||
"filename": "mrtuxa.png",
|
||||
"idiom": "universal",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "3x"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 85 KiB |
|
@ -0,0 +1,61 @@
|
|||
//
|
||||
// ChatModel.swift
|
||||
// Training
|
||||
//
|
||||
// Created by mrtuxa on 27.08.22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct Chat: Identifiable {
|
||||
var id: UUID {
|
||||
person.id
|
||||
}
|
||||
let person: Person
|
||||
var messages: [Message]
|
||||
var hasUnreadMessage = false
|
||||
}
|
||||
|
||||
struct Person: Identifiable {
|
||||
let id = UUID()
|
||||
let name: String
|
||||
let imgString: String
|
||||
}
|
||||
|
||||
|
||||
struct Message: Identifiable {
|
||||
enum MessageType {
|
||||
case Sent, Received
|
||||
}
|
||||
|
||||
let id = UUID()
|
||||
let date: Date
|
||||
let text: String
|
||||
let type: MessageType
|
||||
|
||||
init(_ text: String, type: MessageType, date: Date) {
|
||||
self.date = date
|
||||
self.type = type
|
||||
self.text = text
|
||||
}
|
||||
|
||||
init(_ text: String, type: MessageType) {
|
||||
self.init(text, type: type, date: Date())
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension Chat {
|
||||
|
||||
static let sampleChat = [
|
||||
Chat(person: Person(name: "Josh", imgString: "Unbenannt-1"), messages: [
|
||||
Message("Hey Josh", type: .Sent, date: Date(timeIntervalSinceNow: -86400 * 3)),
|
||||
Message("Ich entwickle gerade einen Whatsapp Clone, aber es ist schon schwer Konversation zu faken. Kannst du mir helfen", type: .Sent, date: Date(timeIntervalSinceNow: -86400 * 3)),
|
||||
], hasUnreadMessage: true),
|
||||
Chat(person: Person(name: "Tobi", imgString: "Unbenannt-1"), messages: [
|
||||
Message("Heute Fortnite", type: .Sent, date: Date(timeIntervalSinceNow: -86400 * 3)),
|
||||
Message("Nein Valo", type: .Received, date: Date()),
|
||||
], hasUnreadMessage: false)
|
||||
]
|
||||
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
//
|
||||
// Created by mrtuxa on 27.08.22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Foundation
|
||||
|
||||
|
||||
struct ChatRow: View {
|
||||
|
||||
let chat: Chat
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 20) {
|
||||
Image(chat.person.imgString)
|
||||
.resizable()
|
||||
.frame(width: 70, height: 70)
|
||||
.clipShape(Circle())
|
||||
|
||||
ZStack {
|
||||
VStack(alignment: .leading, spacing: 5) {
|
||||
HStack {
|
||||
Text(chat.person.name)
|
||||
.bold()
|
||||
}
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
Text(chat.messages.last?.date.descriptiveString() ?? "").multilineTextAlignment(.center)
|
||||
}
|
||||
|
||||
HStack {
|
||||
Text(chat.messages.last?.text ?? "")
|
||||
.lineLimit(1)
|
||||
.frame(height: 50, alignment: .top)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.padding(.trailing, 25)
|
||||
}
|
||||
}
|
||||
Circle()
|
||||
.foregroundColor(chat.hasUnreadMessage ? .blue : .clear)
|
||||
.frame(width: 18, height: 18)
|
||||
.frame(maxWidth: .infinity, alignment: .trailing)
|
||||
}
|
||||
}
|
||||
.frame(height: 80)
|
||||
}
|
||||
}
|
||||
|
||||
struct ChatRow_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ChatRow(chat: Chat.sampleChat[0])
|
||||
}
|
||||
}
|
||||
|
||||
func CurrentDate() -> String {
|
||||
let date = Date()
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.dateFormat = "dd.MM.yyyy"
|
||||
return dateFormatter.string(from: date)
|
||||
}
|
|
@ -0,0 +1,177 @@
|
|||
//
|
||||
// ChatView.swift
|
||||
// Training
|
||||
//
|
||||
// Created by mrtuxa on 28.08.22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
|
||||
struct ChatView: View {
|
||||
|
||||
@EnvironmentObject var viewModel: ChatsViewModel
|
||||
let chat: Chat
|
||||
|
||||
@State private var text = ""
|
||||
@FocusState private var isFocused
|
||||
|
||||
@State private var messageIDToScroll: UUID?
|
||||
|
||||
var navBarLeadingBtn: some View {
|
||||
Button(action: {}) {
|
||||
HStack {
|
||||
Image(chat.person.imgString)
|
||||
.resizable()
|
||||
.frame(width: 40, height: 40)
|
||||
.clipShape(Circle())
|
||||
|
||||
Text(chat.person.name).bold()
|
||||
}.foregroundColor(.black)
|
||||
}
|
||||
}
|
||||
|
||||
var navBarTrailingBtn: some View {
|
||||
HStack {
|
||||
Button(action: {}) {
|
||||
Image(systemName: "video")
|
||||
}
|
||||
Button(action: {}) {
|
||||
Image(systemName: "phone")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
GeometryReader { reader in
|
||||
ScrollView {
|
||||
ScrollViewReader { scrollReader in
|
||||
getMessageView(viewWidth: reader.size.width)
|
||||
.padding(.horizontal)
|
||||
.onChange(of: messageIDToScroll) { _ in
|
||||
if let messageID = messageIDToScroll {
|
||||
scrollTo(messageID: messageID, shouldAnimate: true, scrollReader: scrollReader)
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
if let messageID = chat.messages.last?.id {
|
||||
scrollTo(messageID: messageID, anchor: .bottom, shouldAnimate: false, scrollReader: scrollReader)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
.padding(.bottom, 5)
|
||||
|
||||
toolbarView()
|
||||
}
|
||||
.padding(.top, 1)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.navigationBarItems(leading: navBarLeadingBtn, trailing: navBarTrailingBtn)
|
||||
.onAppear {
|
||||
viewModel.markAsUnread(false, chat: chat)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
func scrollTo(messageID: UUID, anchor: UnitPoint? = nil, shouldAnimate: Bool, scrollReader: ScrollViewProxy) {
|
||||
DispatchQueue.main.async {
|
||||
withAnimation(shouldAnimate ? Animation.easeIn : nil) {
|
||||
scrollReader.scrollTo(messageID, anchor: anchor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func toolbarView() -> some View {
|
||||
VStack {
|
||||
let height: CGFloat = 37
|
||||
HStack {
|
||||
TextField("Message ...", text: $text)
|
||||
.padding(.horizontal, 10)
|
||||
.frame(height: height)
|
||||
.background(Color(UIColor.lightGray))
|
||||
.clipShape(RoundedRectangle(cornerRadius: 13))
|
||||
.focused($isFocused)
|
||||
|
||||
Button(action: sendMessage) {
|
||||
Image(systemName: "paperplane.fill")
|
||||
.foregroundColor(.white)
|
||||
.frame(width: height, height: height)
|
||||
.background(
|
||||
Circle()
|
||||
.foregroundColor(text.isEmpty ? .blue : .green)
|
||||
)
|
||||
}.disabled(text.isEmpty)
|
||||
}.frame(height: height)
|
||||
}
|
||||
.padding(.vertical)
|
||||
.padding(.horizontal)
|
||||
.background(.thickMaterial)
|
||||
}
|
||||
|
||||
func sendMessage() {
|
||||
if let message = viewModel.sendMessage(text, in: chat) {
|
||||
text = ""
|
||||
messageIDToScroll = message.id
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let columns = [GridItem(.flexible(minimum: 10))]
|
||||
|
||||
func getMessageView(viewWidth: CGFloat) -> some View {
|
||||
LazyVGrid(columns: columns, spacing: 0, pinnedViews: [.sectionHeaders]) {
|
||||
let sectionMessages = viewModel.getSectionMessages(for: chat)
|
||||
ForEach(sectionMessages.indices, id: \.self) { sectionIndex in
|
||||
let messages = sectionMessages[sectionIndex]
|
||||
Section(header: sectionHeader(firstMessage: messages.first!)) {
|
||||
ForEach(messages) { message in
|
||||
let isReceived = message.type == .Received
|
||||
HStack {
|
||||
ZStack {
|
||||
Text(message.text)
|
||||
.padding(.horizontal)
|
||||
.padding(.vertical, 12)
|
||||
.background(isReceived ? Color.black.opacity(0.2) : .green.opacity(0.9))
|
||||
.cornerRadius(13)
|
||||
}
|
||||
.background(Color.blue)
|
||||
.padding(.vertical)
|
||||
.frame(width: viewWidth * 0.7, alignment: isReceived ? .leading : .trailing)
|
||||
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: isReceived ? .leading : .trailing)
|
||||
.id(message.id) // important for automatic scrolling later!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sectionHeader(firstMessage message: Message) -> some View {
|
||||
ZStack {
|
||||
Text(message.date.descriptiveString(dateStyle: .medium))
|
||||
.foregroundColor(.white)
|
||||
.font(.system(size: 14, weight: .regular))
|
||||
.frame(width: 120)
|
||||
.padding(.vertical, 5)
|
||||
.background(Capsule().foregroundColor(.cyan))
|
||||
}
|
||||
.padding(.vertical, 5)
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct ChatView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
NavigationView {
|
||||
ChatView(chat: Chat.sampleChat[0])
|
||||
.environmentObject(ChatsViewModel())
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
//
|
||||
// ChatsViewModel.swift
|
||||
// Training
|
||||
//
|
||||
// Created by mrtuxa on 27.08.22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
class ChatsViewModel: ObservableObject {
|
||||
|
||||
@Published var chats = Chat.sampleChat
|
||||
|
||||
func getSortedFilteredChats(query: String) -> [Chat] {
|
||||
let sortedChats = chats.sorted {
|
||||
guard let date1 = $0.messages.last?.date else {
|
||||
return false
|
||||
}
|
||||
guard let date2 = $1.messages.last?.date else {
|
||||
return false
|
||||
}
|
||||
return date1 > date2
|
||||
}
|
||||
|
||||
if query == "" {
|
||||
return sortedChats
|
||||
}
|
||||
return sortedChats.filter {
|
||||
$0.person.name.lowercased().contains(query.lowercased())
|
||||
}
|
||||
}
|
||||
|
||||
func getSectionMessages(for chat: Chat) -> [[Message]] {
|
||||
var res = [[Message]]()
|
||||
var tmp = [Message]()
|
||||
for message in chat.messages {
|
||||
if let firstMessage = tmp.first {
|
||||
let daysBetween = firstMessage.date.daysBetween(date: message.date)
|
||||
if daysBetween >= 1 {
|
||||
res.append(tmp)
|
||||
tmp.removeAll()
|
||||
tmp.append(message)
|
||||
} else {
|
||||
tmp.append(message)
|
||||
}
|
||||
} else {
|
||||
tmp.append(message)
|
||||
}
|
||||
}
|
||||
res.append(tmp)
|
||||
return res
|
||||
}
|
||||
|
||||
func markAsUnread(_ newValue: Bool, chat: Chat) {
|
||||
if let index = chat.messages.firstIndex(where: { $0.id == chat.id }) {
|
||||
chats[index].hasUnreadMessage = newValue
|
||||
}
|
||||
}
|
||||
|
||||
func sendMessage(_ text: String, in chat: Chat) -> Message? {
|
||||
if let index = chats.firstIndex { $0.id == chat.id } {
|
||||
let message = Message(text, type: .Sent)
|
||||
chats[index].messages.append(message)
|
||||
return message
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
//
|
||||
// ContentView.swift
|
||||
// Training
|
||||
//
|
||||
// Created by mrtuxa on 27.08.22.
|
||||
//
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
|
||||
struct ContentView: View {
|
||||
|
||||
@StateObject var viewModel = ChatsViewModel()
|
||||
|
||||
@State private var query = ""
|
||||
|
||||
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
List {
|
||||
ForEach(viewModel.getSortedFilteredChats(query: query)) { chat in
|
||||
|
||||
ZStack {
|
||||
|
||||
ChatRow(chat: chat)
|
||||
|
||||
NavigationLink(destination: {
|
||||
ChatView(chat: chat)
|
||||
.environmentObject(viewModel)
|
||||
}) {
|
||||
EmptyView()
|
||||
}
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
.frame(width: 0)
|
||||
.opacity(0)
|
||||
}
|
||||
.swipeActions(edge: .leading, allowsFullSwipe: true) {
|
||||
Button(action: {
|
||||
viewModel.markAsUnread(!chat.hasUnreadMessage, chat: chat)
|
||||
}) {
|
||||
if chat.hasUnreadMessage {
|
||||
Label("Read", systemImage: "text.bubble")
|
||||
} else {
|
||||
Label("Unread", systemImage: "circle.fill")
|
||||
}
|
||||
}
|
||||
.tint(.blue)
|
||||
}
|
||||
}
|
||||
}
|
||||
.listStyle(PlainListStyle())
|
||||
.searchable(text: $query)
|
||||
.navigationTitle("Chats")
|
||||
.navigationBarItems(trailing: Button(action: {}) {
|
||||
Image(systemName: "square.and.pencil")
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ContentView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ContentView()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
//
|
||||
// Date+Helpers.swift
|
||||
// Training
|
||||
//
|
||||
// Created by mrtuxa on 27.08.22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Date {
|
||||
|
||||
func descriptiveString(dateStyle: DateFormatter.Style = .short) -> String {
|
||||
|
||||
let formatter = DateFormatter()
|
||||
formatter.dateStyle = dateStyle
|
||||
|
||||
let daysBetween = self.daysBetween(date: Date())
|
||||
|
||||
if daysBetween == 0 {
|
||||
return "Today"
|
||||
} else if daysBetween == 1 {
|
||||
return "Yesterday"
|
||||
} else if daysBetween < 5 {
|
||||
let weekdayIndex = Calendar.current.component(.weekday, from: self) - 1
|
||||
return formatter.weekdaySymbols[weekdayIndex]
|
||||
}
|
||||
return formatter.string(from: self)
|
||||
}
|
||||
|
||||
func daysBetween(date: Date) -> Int {
|
||||
let calendar = Calendar.current
|
||||
let date1 = calendar.startOfDay(for: self)
|
||||
let date2 = calendar.startOfDay(for: date)
|
||||
if let daysBetween = calendar.dateComponents([.day], from: date1, to: date2).day {
|
||||
return daysBetween
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
//
|
||||
// TrainingApp.swift
|
||||
// Training
|
||||
//
|
||||
// Created by mrtuxa on 27.08.22.
|
||||
//
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
@main
|
||||
struct TrainingApp: App {
|
||||
var body: some Scene {
|
||||
WindowGroup {
|
||||
ContentView()
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue