Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 267cf26b2e | |||
| c3817bea15 | |||
| 492f51ce9b | |||
| dd72c619d3 | |||
| 43af10de88 | |||
| 7ba97e4893 | |||
| 0c24cb2262 | |||
| 7b76b76b94 | |||
| 565c44677b | |||
| 30dc3679c1 | |||
| 9a18cae265 | |||
| c04654a87b | |||
| bd7f67b3b0 | |||
| 833add707f | |||
| 9118a7688a | |||
| cba1eb36a2 | |||
| d15139d00d | |||
| c1cf9b47d8 | |||
| 986367be38 | |||
| 7d207136b3 | |||
| 0fa3b72a56 | |||
| 67d2bb3f62 | |||
| f2c333f57d | |||
| eccda7a525 | |||
| ac0d9977b5 | |||
| 6c1612f2bb | |||
| ead9bb9c41 | |||
| cc20c54967 | |||
| d5c2dd48f7 | |||
| f4336f1dde | |||
| 7ab91d9440 | |||
| 7e7a168806 | |||
| 9651351ec9 |
@@ -0,0 +1 @@
|
||||
github "pvzig/SlackKit"
|
||||
@@ -0,0 +1,275 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 50;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
262F50452259146E00A74EB1 /* Leaderbot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 262F50432259146E00A74EB1 /* Leaderbot.swift */; };
|
||||
262F50462259146E00A74EB1 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 262F50442259146E00A74EB1 /* main.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
262F50312259139400A74EB1 /* Leaderboard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Leaderboard.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
262F50362259139400A74EB1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
262F50432259146E00A74EB1 /* Leaderbot.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Leaderbot.swift; path = Sources/Leaderbot.swift; sourceTree = "<group>"; };
|
||||
262F50442259146E00A74EB1 /* main.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = main.swift; path = Sources/main.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
262F502F2259139400A74EB1 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
262F50292259139400A74EB1 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
262F50332259139400A74EB1 /* Leaderboard */,
|
||||
262F50322259139400A74EB1 /* Products */,
|
||||
665E45E1CAEDB17C0745AD28 /* Pods */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
262F50322259139400A74EB1 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
262F50312259139400A74EB1 /* Leaderboard.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
262F50332259139400A74EB1 /* Leaderboard */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
262F50432259146E00A74EB1 /* Leaderbot.swift */,
|
||||
262F50442259146E00A74EB1 /* main.swift */,
|
||||
262F50362259139400A74EB1 /* Info.plist */,
|
||||
);
|
||||
path = Leaderboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
665E45E1CAEDB17C0745AD28 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
);
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
262F50302259139400A74EB1 /* Leaderboard */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 262F50392259139400A74EB1 /* Build configuration list for PBXNativeTarget "Leaderboard" */;
|
||||
buildPhases = (
|
||||
262F502E2259139400A74EB1 /* Sources */,
|
||||
262F502F2259139400A74EB1 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = Leaderboard;
|
||||
productName = Leaderboard;
|
||||
productReference = 262F50312259139400A74EB1 /* Leaderboard.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
262F502A2259139400A74EB1 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 1020;
|
||||
LastUpgradeCheck = 1020;
|
||||
ORGANIZATIONNAME = "Peter Zignego";
|
||||
TargetAttributes = {
|
||||
262F50302259139400A74EB1 = {
|
||||
CreatedOnToolsVersion = 10.2;
|
||||
LastSwiftMigration = 1020;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 262F502D2259139400A74EB1 /* Build configuration list for PBXProject "Leaderboard" */;
|
||||
compatibilityVersion = "Xcode 9.3";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = 262F50292259139400A74EB1;
|
||||
productRefGroup = 262F50322259139400A74EB1 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
262F50302259139400A74EB1 /* Leaderboard */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
262F502E2259139400A74EB1 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
262F50462259146E00A74EB1 /* main.swift in Sources */,
|
||||
262F50452259146E00A74EB1 /* Leaderbot.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
262F50372259139400A74EB1 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
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;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
262F50382259139400A74EB1 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
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;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
262F503A2259139400A74EB1 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
FRAMEWORK_SEARCH_PATHS = "\"$(SRCROOT)/Carthage/Build/Mac\"";
|
||||
INFOPLIST_FILE = Leaderboard/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.launchsoft.Leaderboard;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
262F503B2259139400A74EB1 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
FRAMEWORK_SEARCH_PATHS = "\"$(SRCROOT)/Carthage/Build/Mac\"";
|
||||
INFOPLIST_FILE = Leaderboard/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.launchsoft.Leaderboard;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
262F502D2259139400A74EB1 /* Build configuration list for PBXProject "Leaderboard" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
262F50372259139400A74EB1 /* Debug */,
|
||||
262F50382259139400A74EB1 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
262F50392259139400A74EB1 /* Build configuration list for PBXNativeTarget "Leaderboard" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
262F503A2259139400A74EB1 /* Debug */,
|
||||
262F503B2259139400A74EB1 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 262F502A2259139400A74EB1 /* Project object */;
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:Leaderboard.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
+8
@@ -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,28 @@
|
||||
<?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>en</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>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2019 Peter Zignego. All rights reserved.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// Leaderboard.swift
|
||||
//
|
||||
// Copyright © 2017 Peter Zignego. All rights reserved.
|
||||
// Copyright © 2019 Peter Zignego. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -100,7 +100,7 @@ class Leaderbot {
|
||||
let thingRegex = try? NSRegularExpression(pattern: expression, options: [])
|
||||
let things = thingRegex?.matches(in: text, options: [], range: NSMakeRange(0, text.utf16.count)) ?? []
|
||||
for match in things {
|
||||
let value = text.substring(with: text.range(from: match.range(at: 1))!)
|
||||
let value = String(text[text.range(from: match.range(at: 1))!])
|
||||
if leaderboards[teamID]?.scores[value] == nil { leaderboards[teamID]?.scores[value] = 0 }
|
||||
switch trigger {
|
||||
case .plusPlus:
|
||||
@@ -8,11 +8,11 @@ let package = Package(
|
||||
.executable(name: "Leaderboard", targets: ["Leaderboard"]),
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/SlackKit/SlackKit", .upToNextMajor(from: "4.0.0"))
|
||||
.package(url: "https://github.com/pvzig/SlackKit", .upToNextMinor(from: "4.3.0"))
|
||||
],
|
||||
targets: [
|
||||
.target(name: "Leaderboard",
|
||||
dependencies: ["SlackKit"],
|
||||
path: "Sources")
|
||||
dependencies: ["SlackKit"],
|
||||
path: "Leaderboard/Sources")
|
||||
]
|
||||
)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
platform :osx, '10.11'
|
||||
|
||||
target 'Leaderboard' do
|
||||
use_frameworks!
|
||||
pod 'SlackKit', '>= 4.3.0'
|
||||
end
|
||||
@@ -0,0 +1 @@
|
||||
github "pvzig/SlackKit"
|
||||
@@ -8,11 +8,11 @@ let package = Package(
|
||||
.executable(name: "Robot or Not Bot", targets: ["Robot or Not Bot"]),
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/SlackKit/SlackKit", .upToNextMajor(from: "4.0.0"))
|
||||
.package(url: "https://github.com/pvzig/SlackKit", .upToNextMinor(from: "4.3.0"))
|
||||
],
|
||||
targets: [
|
||||
.target(name: "Robot or Not Bot",
|
||||
dependencies: ["SlackKit"],
|
||||
path: "Sources")
|
||||
path: "Robot or Not Bot/Sources")
|
||||
]
|
||||
)
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
platform :osx, '10.11'
|
||||
|
||||
target 'Robot Or Not Bot' do
|
||||
use_frameworks!
|
||||
pod 'SlackKit', '>= 4.3.0'
|
||||
end
|
||||
|
||||
@@ -0,0 +1,263 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 50;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
262F505D22591A9000A74EB1 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 262F505C22591A9000A74EB1 /* main.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
262F504F225919E200A74EB1 /* Robot Or Not Bot.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Robot Or Not Bot.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
262F5054225919E200A74EB1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
262F505C22591A9000A74EB1 /* main.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = main.swift; path = Sources/main.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
262F504D225919E200A74EB1 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
262F5047225919E200A74EB1 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
262F5051225919E200A74EB1 /* Robot Or Not Bot */,
|
||||
262F5050225919E200A74EB1 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
262F5050225919E200A74EB1 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
262F504F225919E200A74EB1 /* Robot Or Not Bot.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
262F5051225919E200A74EB1 /* Robot Or Not Bot */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
262F505C22591A9000A74EB1 /* main.swift */,
|
||||
262F5054225919E200A74EB1 /* Info.plist */,
|
||||
);
|
||||
path = "Robot Or Not Bot";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
262F504E225919E200A74EB1 /* Robot Or Not Bot */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 262F5057225919E200A74EB1 /* Build configuration list for PBXNativeTarget "Robot Or Not Bot" */;
|
||||
buildPhases = (
|
||||
262F504C225919E200A74EB1 /* Sources */,
|
||||
262F504D225919E200A74EB1 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = "Robot Or Not Bot";
|
||||
productName = "Robot Or Not Bot";
|
||||
productReference = 262F504F225919E200A74EB1 /* Robot Or Not Bot.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
262F5048225919E200A74EB1 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 1020;
|
||||
LastUpgradeCheck = 1020;
|
||||
ORGANIZATIONNAME = "Peter Zignego";
|
||||
TargetAttributes = {
|
||||
262F504E225919E200A74EB1 = {
|
||||
CreatedOnToolsVersion = 10.2;
|
||||
LastSwiftMigration = 1020;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 262F504B225919E200A74EB1 /* Build configuration list for PBXProject "Robot Or Not Bot" */;
|
||||
compatibilityVersion = "Xcode 9.3";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = 262F5047225919E200A74EB1;
|
||||
productRefGroup = 262F5050225919E200A74EB1 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
262F504E225919E200A74EB1 /* Robot Or Not Bot */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
262F504C225919E200A74EB1 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
262F505D22591A9000A74EB1 /* main.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
262F5055225919E200A74EB1 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
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;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
262F5056225919E200A74EB1 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
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;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
262F5058225919E200A74EB1 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
FRAMEWORK_SEARCH_PATHS = "\"$(SRCROOT)/Carthage/Build/Mac\"";
|
||||
INFOPLIST_FILE = "Robot Or Not Bot/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.launchsoft.Robot-Or-Not-Bot";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
262F5059225919E200A74EB1 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
FRAMEWORK_SEARCH_PATHS = "\"$(SRCROOT)/Carthage/Build/Mac\"";
|
||||
INFOPLIST_FILE = "Robot Or Not Bot/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.launchsoft.Robot-Or-Not-Bot";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
262F504B225919E200A74EB1 /* Build configuration list for PBXProject "Robot Or Not Bot" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
262F5055225919E200A74EB1 /* Debug */,
|
||||
262F5056225919E200A74EB1 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
262F5057225919E200A74EB1 /* Build configuration list for PBXNativeTarget "Robot Or Not Bot" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
262F5058225919E200A74EB1 /* Debug */,
|
||||
262F5059225919E200A74EB1 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 262F5048225919E200A74EB1 /* Project object */;
|
||||
}
|
||||
Generated
+7
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:Robot Or Not Bot.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
+8
@@ -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,28 @@
|
||||
<?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>en</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>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2019 Peter Zignego. All rights reserved.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
+1
-1
@@ -58,7 +58,7 @@ let package = Package(
|
||||
.library(name: "SlackKit", targets: ["SlackKit"]),
|
||||
.library(name: "SKClient", targets: ["SKClient"]),
|
||||
.library(name: "SKCore", targets: ["SKCore"]),
|
||||
.library(name: "SKRMTAPI", targets: ["SKRTMAPI"]),
|
||||
.library(name: "SKRTMAPI", targets: ["SKRTMAPI"]),
|
||||
.library(name: "SKServer", targets: ["SKServer"]),
|
||||
.library(name: "SKWebAPI", targets: ["SKWebAPI"])
|
||||
],
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[](https://dev.azure.com/pzignego/SlackKit/_build/latest?definitionId=2&branchName=master)
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
[](https://github.com/apple/swift-package-manager)
|
||||
@@ -25,7 +25,7 @@ Add `SlackKit` to your `Package.swift`
|
||||
```swift
|
||||
let package = Package(
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/pvzig/SlackKit.git", .upToNextMinor(from: "4.2.0"))
|
||||
.package(url: "https://github.com/pvzig/SlackKit.git", .upToNextMinor(from: "4.3.0"))
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ let package = Package(
|
||||
targets: ["SampleApp"]),
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/pvzig/SlackKit.git", .upToNextMinor(from: "4.2.0")),
|
||||
.package(url: "https://github.com/pvzig/SlackKit.git", .upToNextMinor(from: "4.3.0")),
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
|
||||
+126
-36
@@ -22,6 +22,18 @@
|
||||
// THE SOFTWARE.
|
||||
|
||||
public struct Action {
|
||||
fileprivate enum CodingKeys: String {
|
||||
case name
|
||||
case text
|
||||
case type
|
||||
case value
|
||||
case url
|
||||
case style
|
||||
case confirm
|
||||
case options
|
||||
case dataSource = "data_source"
|
||||
}
|
||||
|
||||
public let name: String?
|
||||
public let text: String?
|
||||
public let type: String?
|
||||
@@ -31,17 +43,17 @@ public struct Action {
|
||||
public let confirm: Confirm?
|
||||
public let options: [Option]?
|
||||
public let dataSource: DataSource?
|
||||
|
||||
|
||||
public init(action: [String: Any]?) {
|
||||
name = action?["name"] as? String
|
||||
text = action?["text"] as? String
|
||||
type = action?["type"] as? String
|
||||
value = action?["value"] as? String
|
||||
url = action?["url"] as? String
|
||||
style = ActionStyle(rawValue: action?["style"] as? String ?? "")
|
||||
confirm = Confirm(confirm:action?["confirm"] as? [String: Any])
|
||||
options = (action?["options"] as? [[String: Any]])?.map { Option(option: $0) }
|
||||
dataSource = DataSource(rawValue: action?["data_source"] as? String ?? "")
|
||||
name = action?[CodingKeys.name.rawValue] as? String
|
||||
text = action?[CodingKeys.text.rawValue] as? String
|
||||
type = action?[CodingKeys.type.rawValue] as? String
|
||||
value = action?[CodingKeys.value.rawValue] as? String
|
||||
url = action?[CodingKeys.url.rawValue] as? String
|
||||
style = ActionStyle(rawValue: action?[CodingKeys.style.rawValue] as? String ?? "")
|
||||
confirm = Confirm(confirm:action?[CodingKeys.confirm.rawValue] as? [String: Any])
|
||||
options = (action?[CodingKeys.options.rawValue] as? [[String: Any]])?.map { Option(option: $0) }
|
||||
dataSource = DataSource(rawValue: action?[CodingKeys.dataSource.rawValue] as? String ?? "")
|
||||
}
|
||||
|
||||
public init(name: String, text: String, type: String = "button", style: ActionStyle = .defaultStyle, value: String? = nil,
|
||||
@@ -59,29 +71,36 @@ public struct Action {
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var dict = [String: Any]()
|
||||
dict["name"] = name
|
||||
dict["text"] = text
|
||||
dict["type"] = type
|
||||
dict["value"] = value
|
||||
dict["url"] = url
|
||||
dict["style"] = style?.rawValue
|
||||
dict["confirm"] = confirm?.dictionary
|
||||
dict["options"] = options?.map { $0.dictionary }
|
||||
dict["data_source"] = dataSource?.rawValue
|
||||
dict[CodingKeys.name.rawValue] = name
|
||||
dict[CodingKeys.text.rawValue] = text
|
||||
dict[CodingKeys.type.rawValue] = type
|
||||
dict[CodingKeys.value.rawValue] = value
|
||||
dict[CodingKeys.url.rawValue] = url
|
||||
dict[CodingKeys.style.rawValue] = style?.rawValue
|
||||
dict[CodingKeys.confirm.rawValue] = confirm?.dictionary
|
||||
dict[CodingKeys.options.rawValue] = options?.map { $0.dictionary }
|
||||
dict[CodingKeys.dataSource.rawValue] = dataSource?.rawValue
|
||||
return dict
|
||||
}
|
||||
|
||||
public struct Confirm {
|
||||
fileprivate enum CodingKeys: String {
|
||||
case title
|
||||
case text
|
||||
case okText = "ok_text"
|
||||
case dismissText = "dismiss_text"
|
||||
}
|
||||
|
||||
public let title: String?
|
||||
public let text: String?
|
||||
public let okText: String?
|
||||
public let dismissText: String?
|
||||
|
||||
|
||||
public init(confirm: [String: Any]?) {
|
||||
title = confirm?["title"] as? String
|
||||
text = confirm?["text"] as? String
|
||||
okText = confirm?["ok_text"] as? String
|
||||
dismissText = confirm?["dismiss_text"] as? String
|
||||
title = confirm?[CodingKeys.title.rawValue] as? String
|
||||
text = confirm?[CodingKeys.text.rawValue] as? String
|
||||
okText = confirm?[CodingKeys.okText.rawValue] as? String
|
||||
dismissText = confirm?[CodingKeys.dismissText.rawValue] as? String
|
||||
}
|
||||
|
||||
public init(text: String, title: String? = nil, okText: String? = nil, dismissText: String? = nil) {
|
||||
@@ -93,21 +112,26 @@ public struct Action {
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var dict = [String: Any]()
|
||||
dict["title"] = title
|
||||
dict["text"] = text
|
||||
dict["ok_text"] = okText
|
||||
dict["dismiss_text"] = dismissText
|
||||
dict[CodingKeys.title.rawValue] = title
|
||||
dict[CodingKeys.text.rawValue] = text
|
||||
dict[CodingKeys.okText.rawValue] = okText
|
||||
dict[CodingKeys.dismissText.rawValue] = dismissText
|
||||
return dict
|
||||
}
|
||||
}
|
||||
|
||||
public struct Option {
|
||||
fileprivate enum CodingKeys: String {
|
||||
case text
|
||||
case value
|
||||
}
|
||||
|
||||
public let text: String?
|
||||
public let value: String?
|
||||
|
||||
|
||||
public init(option: [String: Any]?) {
|
||||
text = option?["text"] as? String
|
||||
value = option?["value"] as? String
|
||||
text = option?[CodingKeys.text.rawValue] as? String
|
||||
value = option?[CodingKeys.value.rawValue] as? String
|
||||
}
|
||||
|
||||
public init(text: String, value: String) {
|
||||
@@ -117,26 +141,92 @@ public struct Action {
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var dict = [String: Any]()
|
||||
dict["text"] = text
|
||||
dict["value"] = value
|
||||
dict[CodingKeys.text.rawValue] = text
|
||||
dict[CodingKeys.value.rawValue] = value
|
||||
return dict
|
||||
}
|
||||
}
|
||||
|
||||
public enum DataSource: String {
|
||||
public enum DataSource: String, Codable {
|
||||
case users
|
||||
case channels
|
||||
case conversations
|
||||
}
|
||||
}
|
||||
|
||||
public enum ActionStyle: String {
|
||||
extension Action: Codable {
|
||||
public init(from decoder: Decoder) throws {
|
||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||
name = try values.decodeIfPresent(String.self, forKey: .name)
|
||||
text = try values.decodeIfPresent(String.self, forKey: .text)
|
||||
type = try values.decodeIfPresent(String.self, forKey: .type)
|
||||
value = try values.decodeIfPresent(String.self, forKey: .value)
|
||||
url = try values.decodeIfPresent(String.self, forKey: .url)
|
||||
style = try values.decodeIfPresent(ActionStyle.self, forKey: .style)
|
||||
confirm = try values.decodeIfPresent(Confirm.self, forKey: .confirm)
|
||||
options = try values.decodeIfPresent([Option].self, forKey: .options)
|
||||
dataSource = try values.decodeIfPresent(DataSource.self, forKey: .dataSource)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(name, forKey: .name)
|
||||
try container.encode(text, forKey: .text)
|
||||
try container.encode(type, forKey: .type)
|
||||
try container.encode(value, forKey: .value)
|
||||
try container.encode(url, forKey: .url)
|
||||
try container.encode(style, forKey: .style)
|
||||
try container.encode(confirm, forKey: .confirm)
|
||||
try container.encode(options, forKey: .options)
|
||||
try container.encode(dataSource, forKey: .dataSource)
|
||||
}
|
||||
}
|
||||
|
||||
extension Action.CodingKeys: CodingKey { }
|
||||
|
||||
extension Action.Confirm: Codable {
|
||||
public init(from decoder: Decoder) throws {
|
||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||
title = try values.decodeIfPresent(String.self, forKey: .title)
|
||||
text = try values.decodeIfPresent(String.self, forKey: .text)
|
||||
okText = try values.decodeIfPresent(String.self, forKey: .okText)
|
||||
dismissText = try values.decodeIfPresent(String.self, forKey: .dismissText)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(title, forKey: .title)
|
||||
try container.encode(text, forKey: .text)
|
||||
try container.encode(okText, forKey: .okText)
|
||||
try container.encode(dismissText, forKey: .dismissText)
|
||||
}
|
||||
}
|
||||
|
||||
extension Action.Confirm.CodingKeys: CodingKey { }
|
||||
|
||||
extension Action.Option: Codable {
|
||||
public init(from decoder: Decoder) throws {
|
||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||
text = try values.decodeIfPresent(String.self, forKey: .text)
|
||||
value = try values.decodeIfPresent(String.self, forKey: .value)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(text, forKey: .text)
|
||||
try container.encode(value, forKey: .value)
|
||||
}
|
||||
}
|
||||
|
||||
extension Action.Option.CodingKeys: CodingKey { }
|
||||
|
||||
public enum ActionStyle: String, Codable {
|
||||
case defaultStyle = "default"
|
||||
case primary = "primary"
|
||||
case danger = "danger"
|
||||
}
|
||||
|
||||
public enum MessageResponseType: String {
|
||||
public enum MessageResponseType: String, Codable {
|
||||
case inChannel = "in_channel"
|
||||
case ephemeral = "ephemeral"
|
||||
}
|
||||
|
||||
@@ -22,14 +22,20 @@
|
||||
// THE SOFTWARE.
|
||||
|
||||
public struct AttachmentField {
|
||||
fileprivate enum CodingKeys: String {
|
||||
case title
|
||||
case value
|
||||
case short
|
||||
}
|
||||
|
||||
public let title: String?
|
||||
public let value: String?
|
||||
public let short: Bool?
|
||||
|
||||
|
||||
public init(field: [String: Any]?) {
|
||||
title = field?["title"] as? String
|
||||
value = field?["value"] as? String
|
||||
short = field?["short"] as? Bool
|
||||
title = field?[CodingKeys.title.rawValue] as? String
|
||||
value = field?[CodingKeys.value.rawValue] as? String
|
||||
short = field?[CodingKeys.short.rawValue] as? Bool
|
||||
}
|
||||
|
||||
public init(title: String?, value: String?, short: Bool? = nil) {
|
||||
@@ -40,9 +46,27 @@ public struct AttachmentField {
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var field = [String: Any]()
|
||||
field["title"] = title
|
||||
field["value"] = value
|
||||
field["short"] = short
|
||||
field[CodingKeys.title.rawValue] = title
|
||||
field[CodingKeys.value.rawValue] = value
|
||||
field[CodingKeys.short.rawValue] = short
|
||||
return field
|
||||
}
|
||||
}
|
||||
|
||||
extension AttachmentField: Codable {
|
||||
public init(from decoder: Decoder) throws {
|
||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||
title = try values.decodeIfPresent(String.self, forKey: .title)
|
||||
value = try values.decodeIfPresent(String.self, forKey: .value)
|
||||
short = try values.decodeIfPresent(Bool.self, forKey: .short)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(title, forKey: .title)
|
||||
try container.encode(value, forKey: .value)
|
||||
try container.encode(short, forKey: .short)
|
||||
}
|
||||
}
|
||||
|
||||
extension AttachmentField.CodingKeys: CodingKey { }
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/// Defined by https://api.slack.com/reference/messaging/composition-objects#text
|
||||
public struct TextComposition {
|
||||
/// The type of block. Can be one of plainText or markdown.
|
||||
public let type: BlockType
|
||||
public let text: String
|
||||
public let emoji: Bool?
|
||||
public let verbatim: Bool?
|
||||
|
||||
public init(type: BlockType,
|
||||
text: String,
|
||||
emoji: Bool? = nil,
|
||||
verbatim: Bool? = nil) {
|
||||
self.type = type
|
||||
self.text = text
|
||||
self.emoji = emoji
|
||||
self.verbatim = verbatim
|
||||
}
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var composition = [String: Any]()
|
||||
composition["type"] = type.rawValue
|
||||
composition["text"] = text
|
||||
composition["emoji"] = emoji
|
||||
composition["verbatim"] = verbatim
|
||||
return composition
|
||||
}
|
||||
}
|
||||
|
||||
/// Defined by https://api.slack.com/reference/messaging/composition-objects#option
|
||||
public struct OptionComposition {
|
||||
public let text: TextComposition
|
||||
public let value: String
|
||||
public let url: String?
|
||||
|
||||
public init(text: TextComposition,
|
||||
value: String,
|
||||
url: String? = nil) {
|
||||
self.text = text
|
||||
self.value = value
|
||||
self.url = url
|
||||
}
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var composition = [String: Any]()
|
||||
composition["text"] = text.dictionary
|
||||
composition["value"] = value
|
||||
composition["url"] = url
|
||||
return composition
|
||||
}
|
||||
}
|
||||
|
||||
/// Defined by https://api.slack.com/reference/messaging/composition-objects#option-group
|
||||
public struct OptionGroupComposition {
|
||||
public let label: TextComposition
|
||||
public let options: [OptionComposition]
|
||||
|
||||
public init(label: TextComposition,
|
||||
options: [OptionComposition]) {
|
||||
self.label = label
|
||||
self.options = options
|
||||
}
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var composition = [String: Any]()
|
||||
composition["label"] = label.dictionary
|
||||
composition["options"] = options.map { $0.dictionary }
|
||||
return composition
|
||||
}
|
||||
}
|
||||
|
||||
/// Defined by https://api.slack.com/reference/messaging/composition-objects#confirm
|
||||
public struct ConfirmComposition {
|
||||
public let title: TextComposition
|
||||
public let text: TextComposition
|
||||
public let confirm: TextComposition
|
||||
public let deny: TextComposition
|
||||
|
||||
public init(title: TextComposition,
|
||||
text: TextComposition,
|
||||
confirm: TextComposition,
|
||||
deny: TextComposition) {
|
||||
self.title = title
|
||||
self.text = text
|
||||
self.confirm = confirm
|
||||
self.deny = deny
|
||||
}
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var composition = [String: Any]()
|
||||
composition["title"] = title.dictionary
|
||||
composition["text"] = text.dictionary
|
||||
composition["confirm"] = confirm.dictionary
|
||||
composition["deny"] = deny.dictionary
|
||||
return composition
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,354 @@
|
||||
public protocol BlockElement {
|
||||
var dictionary: [String: Any] { get }
|
||||
}
|
||||
|
||||
public protocol SectionElement: BlockElement {}
|
||||
|
||||
public protocol ActionsElement: BlockElement {}
|
||||
|
||||
public protocol ContextElement: BlockElement {}
|
||||
|
||||
/// Defined by https://api.slack.com/reference/messaging/block-elements#image
|
||||
public struct ImageElement: BlockElement, SectionElement, ContextElement {
|
||||
/// Type will always be image.
|
||||
public let type: BlockType
|
||||
public let imageURL: String
|
||||
public let altText: String
|
||||
|
||||
public init(type: BlockType = .image,
|
||||
imageURL: String,
|
||||
altText: String) {
|
||||
self.type = type
|
||||
self.imageURL = imageURL
|
||||
self.altText = altText
|
||||
}
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var element = [String: Any]()
|
||||
element["type"] = type.rawValue
|
||||
element["image_url"] = imageURL
|
||||
element["alt_text"] = altText
|
||||
return element
|
||||
}
|
||||
}
|
||||
|
||||
/// Custom type to better support Context PlainText
|
||||
public struct PlainTextElement: BlockElement, ContextElement {
|
||||
/// Type will always be image.
|
||||
public let type: BlockType
|
||||
public let text: String
|
||||
|
||||
public init(type: BlockType = .plainText,
|
||||
text: String) {
|
||||
self.type = type
|
||||
self.text = text
|
||||
}
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var element = [String: Any]()
|
||||
element["type"] = type.rawValue
|
||||
element["text"] = text
|
||||
return element
|
||||
}
|
||||
}
|
||||
|
||||
/// Custom type to better support Context Markdown Text
|
||||
public struct MarkdownTextElement: BlockElement, ContextElement {
|
||||
/// Type will always be image.
|
||||
public let type: BlockType
|
||||
public let text: String
|
||||
|
||||
public init(type: BlockType = .markdown,
|
||||
text: String) {
|
||||
self.type = type
|
||||
self.text = text
|
||||
}
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var element = [String: Any]()
|
||||
element["type"] = type.rawValue
|
||||
element["text"] = text
|
||||
return element
|
||||
}
|
||||
}
|
||||
|
||||
public enum ButtonElementStyle: String, CaseIterable {
|
||||
case `default`
|
||||
case primary
|
||||
case danger
|
||||
}
|
||||
|
||||
/// Defined by https://api.slack.com/reference/messaging/block-elements#button
|
||||
public struct ButtonElement: BlockElement, SectionElement, ActionsElement {
|
||||
/// Type will always be button.
|
||||
public let type: BlockType
|
||||
public let text: TextComposition
|
||||
public let actionId: String
|
||||
public let url: String?
|
||||
public let value: String?
|
||||
public let style: ButtonElementStyle?
|
||||
|
||||
public init(type: BlockType = .button,
|
||||
text: TextComposition,
|
||||
actionId: String,
|
||||
url: String? = nil,
|
||||
value: String? = nil,
|
||||
style: ButtonElementStyle? = nil) {
|
||||
self.type = type
|
||||
self.text = text
|
||||
self.actionId = actionId
|
||||
self.url = url
|
||||
self.value = value
|
||||
self.style = style
|
||||
}
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var element = [String: Any]()
|
||||
element["type"] = type.rawValue
|
||||
element["text"] = text.dictionary
|
||||
element["action_id"] = actionId
|
||||
element["url"] = url
|
||||
element["value"] = value
|
||||
element["style"] = style
|
||||
return element
|
||||
}
|
||||
}
|
||||
|
||||
/// Defined by https://api.slack.com/reference/messaging/block-elements#static-select
|
||||
public struct StaticSelectElement: BlockElement, SectionElement, ActionsElement {
|
||||
/// Type will always be static_select.
|
||||
public let type: BlockType
|
||||
public let placeholder: TextComposition
|
||||
public let actionId: String
|
||||
public let options: [OptionComposition]?
|
||||
public let optionGroups: [OptionGroupComposition]?
|
||||
public let initialOption: OptionComposition?
|
||||
public let initialOptionGroup: OptionGroupComposition?
|
||||
public let confirm: ConfirmComposition?
|
||||
|
||||
public init(type: BlockType = .staticSelect,
|
||||
placeholder: TextComposition,
|
||||
actionId: String,
|
||||
options: [OptionComposition]? = nil,
|
||||
optionGroups: [OptionGroupComposition]? = nil,
|
||||
initialOption: OptionComposition? = nil,
|
||||
initialOptionGroup: OptionGroupComposition? = nil,
|
||||
confirm: ConfirmComposition? = nil) {
|
||||
self.type = type
|
||||
self.placeholder = placeholder
|
||||
self.actionId = actionId
|
||||
self.options = options
|
||||
self.optionGroups = optionGroups
|
||||
self.initialOption = initialOption
|
||||
self.initialOptionGroup = initialOptionGroup
|
||||
self.confirm = confirm
|
||||
}
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var element = [String: Any]()
|
||||
element["type"] = type.rawValue
|
||||
element["placeholder"] = placeholder.dictionary
|
||||
element["action_id"] = actionId
|
||||
element["options"] = options?.map { $0.dictionary }
|
||||
element["option_groups"] = optionGroups?.map { $0.dictionary }
|
||||
element["initial_option"] = initialOption?.dictionary ?? initialOptionGroup?.dictionary
|
||||
element["confirm"] = confirm?.dictionary
|
||||
return element
|
||||
}
|
||||
}
|
||||
|
||||
/// Defined by https://api.slack.com/reference/messaging/block-elements#external-select
|
||||
public struct ExternalSelectElement: BlockElement, SectionElement, ActionsElement {
|
||||
/// Type will always be externalSelect.
|
||||
public let type: BlockType
|
||||
public let placeholder: TextComposition
|
||||
public let actionId: String
|
||||
public let initialOption: OptionComposition?
|
||||
public let initialOptionGroup: OptionGroupComposition?
|
||||
public let minQueryLenght: Int?
|
||||
public let confirm: ConfirmComposition?
|
||||
|
||||
public init(type: BlockType = .externalSelect,
|
||||
placeholder: TextComposition,
|
||||
actionId: String,
|
||||
initialOption: OptionComposition? = nil,
|
||||
initialOptionGroup: OptionGroupComposition? = nil,
|
||||
minQueryLenght: Int?,
|
||||
confirm: ConfirmComposition? = nil) {
|
||||
self.type = type
|
||||
self.placeholder = placeholder
|
||||
self.actionId = actionId
|
||||
self.initialOption = initialOption
|
||||
self.initialOptionGroup = initialOptionGroup
|
||||
self.minQueryLenght = minQueryLenght
|
||||
self.confirm = confirm
|
||||
}
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var element = [String: Any]()
|
||||
element["type"] = type.rawValue
|
||||
element["placeholder"] = placeholder.dictionary
|
||||
element["action_id"] = actionId
|
||||
element["initial_option"] = initialOption?.dictionary ?? initialOptionGroup?.dictionary
|
||||
element["min_query_length"] = minQueryLenght
|
||||
element["confirm"] = confirm?.dictionary
|
||||
return element
|
||||
}
|
||||
}
|
||||
|
||||
/// Defined by https://api.slack.com/reference/messaging/block-elements#user-select
|
||||
public struct UsersSelectElement: BlockElement, SectionElement, ActionsElement {
|
||||
/// Type will always be usersSelect.
|
||||
public let type: BlockType
|
||||
public let placeholder: TextComposition
|
||||
public let actionId: String
|
||||
public let initialUserId: String?
|
||||
public let confirm: ConfirmComposition?
|
||||
|
||||
public init(type: BlockType = .usersSelect,
|
||||
placeholder: TextComposition,
|
||||
actionId: String,
|
||||
initialUserId: String?,
|
||||
confirm: ConfirmComposition? = nil) {
|
||||
self.type = type
|
||||
self.placeholder = placeholder
|
||||
self.actionId = actionId
|
||||
self.initialUserId = initialUserId
|
||||
self.confirm = confirm
|
||||
}
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var element = [String: Any]()
|
||||
element["type"] = type.rawValue
|
||||
element["placeholder"] = placeholder.dictionary
|
||||
element["action_id"] = actionId
|
||||
element["initial_user"] = initialUserId
|
||||
element["confirm"] = confirm?.dictionary
|
||||
return element
|
||||
}
|
||||
}
|
||||
|
||||
/// Defined by https://api.slack.com/reference/messaging/block-elements#converstation-select
|
||||
public struct ConverstationSelectElement: BlockElement, SectionElement, ActionsElement {
|
||||
/// Type will always be converstationSelect.
|
||||
public let type: BlockType
|
||||
public let placeholder: TextComposition
|
||||
public let actionId: String
|
||||
public let initialConverstationId: String?
|
||||
public let confirm: ConfirmComposition?
|
||||
|
||||
public init(type: BlockType = .converstationSelect,
|
||||
placeholder: TextComposition,
|
||||
actionId: String,
|
||||
initialConverstationId: String?,
|
||||
confirm: ConfirmComposition? = nil) {
|
||||
self.type = type
|
||||
self.placeholder = placeholder
|
||||
self.actionId = actionId
|
||||
self.initialConverstationId = initialConverstationId
|
||||
self.confirm = confirm
|
||||
}
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var element = [String: Any]()
|
||||
element["type"] = type.rawValue
|
||||
element["placeholder"] = placeholder.dictionary
|
||||
element["action_id"] = actionId
|
||||
element["initial_conversation"] = initialConverstationId
|
||||
element["confirm"] = confirm?.dictionary
|
||||
return element
|
||||
}
|
||||
}
|
||||
|
||||
/// Defined by https://api.slack.com/reference/messaging/block-elements#channel-select
|
||||
public struct ChannelSelectElement: BlockElement, SectionElement, ActionsElement {
|
||||
/// Type will always be channelSelect.
|
||||
public let type: BlockType
|
||||
public let placeholder: TextComposition
|
||||
public let actionId: String
|
||||
public let initialChannelId: String?
|
||||
public let confirm: ConfirmComposition?
|
||||
|
||||
public init(type: BlockType = .channelSelect,
|
||||
placeholder: TextComposition,
|
||||
actionId: String,
|
||||
initialChannelId: String?,
|
||||
confirm: ConfirmComposition? = nil) {
|
||||
self.type = type
|
||||
self.placeholder = placeholder
|
||||
self.actionId = actionId
|
||||
self.initialChannelId = initialChannelId
|
||||
self.confirm = confirm
|
||||
}
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var element = [String: Any]()
|
||||
element["type"] = type.rawValue
|
||||
element["placeholder"] = placeholder.dictionary
|
||||
element["action_id"] = actionId
|
||||
element["initial_channel"] = initialChannelId
|
||||
element["confirm"] = confirm?.dictionary
|
||||
return element
|
||||
}
|
||||
}
|
||||
|
||||
/// Defined by https://api.slack.com/reference/messaging/block-elements#overflow
|
||||
public struct OverflowElement: BlockElement, SectionElement, ActionsElement {
|
||||
/// Type will always be overflow.
|
||||
public let type: BlockType
|
||||
public let actionId: String
|
||||
public let options: [OptionComposition]
|
||||
public let confirm: ConfirmComposition?
|
||||
|
||||
public init(type: BlockType = .overflow,
|
||||
placeholder: TextComposition,
|
||||
actionId: String,
|
||||
options: [OptionComposition],
|
||||
confirm: ConfirmComposition? = nil) {
|
||||
self.type = type
|
||||
self.actionId = actionId
|
||||
self.options = options
|
||||
self.confirm = confirm
|
||||
}
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var element = [String: Any]()
|
||||
element["type"] = type.rawValue
|
||||
element["action_id"] = actionId
|
||||
element["options"] = options
|
||||
element["confirm"] = confirm?.dictionary
|
||||
return element
|
||||
}
|
||||
}
|
||||
|
||||
/// Defined by https://api.slack.com/reference/messaging/block-elements#overflow
|
||||
public struct DatePickerElement: BlockElement, SectionElement, ActionsElement {
|
||||
/// Type will always be datePicker.
|
||||
public let type: BlockType
|
||||
public let actionId: String
|
||||
public let placeholder: TextComposition?
|
||||
public let initialDate: String?
|
||||
public let confirm: ConfirmComposition?
|
||||
|
||||
public init(type: BlockType = .datePicker,
|
||||
actionId: String,
|
||||
placeholder: TextComposition?,
|
||||
initialDate: String? = nil,
|
||||
confirm: ConfirmComposition? = nil) {
|
||||
self.type = type
|
||||
self.actionId = actionId
|
||||
self.placeholder = placeholder
|
||||
self.initialDate = initialDate
|
||||
self.confirm = confirm
|
||||
}
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var element = [String: Any]()
|
||||
element["type"] = type.rawValue
|
||||
element["action_id"] = actionId
|
||||
element["placeholder"] = placeholder?.dictionary
|
||||
element["initial_date"] = initialDate
|
||||
element["confirm"] = confirm?.dictionary
|
||||
return element
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
public protocol Block {
|
||||
var dictionary: [String: Any] { get }
|
||||
}
|
||||
|
||||
public enum BlockType: String, CaseIterable {
|
||||
case actions
|
||||
case button
|
||||
case context
|
||||
case datePicker = "datepicker"
|
||||
case divider
|
||||
case image
|
||||
case markdown = "mrkdwn"
|
||||
case overflow
|
||||
case plainText = "plain_text"
|
||||
case section
|
||||
|
||||
// Selects
|
||||
|
||||
case channelSelect = "channels_select"
|
||||
case converstationSelect = "conversations_select"
|
||||
case externalSelect = "external_select"
|
||||
case staticSelect = "static_select"
|
||||
case usersSelect = "users_select"
|
||||
}
|
||||
|
||||
/// Defined by https://api.slack.com/reference/messaging/blocks#section
|
||||
public struct SectionBlock: Block {
|
||||
/// Type will always be section.
|
||||
public let type: BlockType
|
||||
public let text: TextComposition
|
||||
public let blockId: String?
|
||||
public let fields: [TextComposition]?
|
||||
public let accessory: SectionElement?
|
||||
|
||||
public init(type: BlockType = .section,
|
||||
text: TextComposition,
|
||||
blockId: String? = nil,
|
||||
fields: [TextComposition]? = nil,
|
||||
accessory: SectionElement? = nil) {
|
||||
self.type = type
|
||||
self.text = text
|
||||
self.blockId = blockId
|
||||
self.fields = fields
|
||||
self.accessory = accessory
|
||||
}
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var block = [String: Any]()
|
||||
block["type"] = type.rawValue
|
||||
block["text"] = text.dictionary
|
||||
block["block_id"] = blockId
|
||||
block["fields"] = fields?.map { $0.dictionary }
|
||||
block["accessory"] = accessory?.dictionary
|
||||
return block
|
||||
}
|
||||
}
|
||||
|
||||
/// Defined by https://api.slack.com/reference/messaging/blocks#divider
|
||||
public struct DividerBlock: Block {
|
||||
/// Type will always be divider.
|
||||
public let type: BlockType
|
||||
public let blockId: String?
|
||||
|
||||
public init(type: BlockType = .divider,
|
||||
blockId: String? = nil) {
|
||||
self.type = type
|
||||
self.blockId = blockId
|
||||
}
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var block = [String: Any]()
|
||||
block["type"] = type
|
||||
block["block_id"] = blockId
|
||||
return block
|
||||
}
|
||||
}
|
||||
|
||||
/// Defined by https://api.slack.com/reference/messaging/blocks#image
|
||||
public struct ImageBlock: Block {
|
||||
/// Type will always be image.
|
||||
public let type: BlockType
|
||||
public let imageURL: String
|
||||
public let altText: String
|
||||
public let title: String?
|
||||
public let blockId: String?
|
||||
|
||||
public init(type: BlockType = .image,
|
||||
imageURL: String,
|
||||
altText: String,
|
||||
title: String? = nil,
|
||||
blockId: String? = nil) {
|
||||
self.type = type
|
||||
self.imageURL = imageURL
|
||||
self.altText = altText
|
||||
self.title = title
|
||||
self.blockId = blockId
|
||||
}
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var block = [String: Any]()
|
||||
block["type"] = type.rawValue
|
||||
block["image_url"] = imageURL
|
||||
block["alt_text"] = altText
|
||||
block["title"] = title
|
||||
block["block_id"] = blockId
|
||||
return block
|
||||
}
|
||||
}
|
||||
|
||||
/// Defined by https://api.slack.com/reference/messaging/blocks#actions
|
||||
public struct ActionsBlock: Block {
|
||||
/// Type will always be actions.
|
||||
public let type: BlockType
|
||||
public let elements: [ActionsElement]
|
||||
public let blockId: String?
|
||||
|
||||
public init(type: BlockType = .actions,
|
||||
elements: [ActionsElement],
|
||||
blockId: String? = nil) {
|
||||
self.type = type
|
||||
self.elements = elements
|
||||
self.blockId = blockId
|
||||
}
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var block = [String: Any]()
|
||||
block["type"] = type.rawValue
|
||||
block["elements"] = elements.map { $0.dictionary }
|
||||
block["block_id"] = blockId
|
||||
return block
|
||||
}
|
||||
}
|
||||
|
||||
/// Defined by https://api.slack.com/reference/messaging/blocks#context
|
||||
public struct ContextBlock: Block {
|
||||
/// Type will always be actions.
|
||||
public let type: BlockType
|
||||
public let elements: [ContextElement]
|
||||
public let blockId: String?
|
||||
|
||||
public init(type: BlockType = .context,
|
||||
elements: [ContextElement],
|
||||
blockId: String? = nil) {
|
||||
self.type = type
|
||||
self.elements = elements
|
||||
self.blockId = blockId
|
||||
}
|
||||
|
||||
public var dictionary: [String: Any] {
|
||||
var block = [String: Any]()
|
||||
block["type"] = type.rawValue
|
||||
block["elements"] = elements.map { $0.dictionary }
|
||||
block["block_id"] = blockId
|
||||
return block
|
||||
}
|
||||
}
|
||||
@@ -22,11 +22,32 @@
|
||||
// THE SOFTWARE.
|
||||
|
||||
public struct Edited {
|
||||
fileprivate enum CodingKeys: String {
|
||||
case user
|
||||
case ts
|
||||
}
|
||||
|
||||
public let user: String?
|
||||
public let ts: String?
|
||||
|
||||
public init(edited: [String: Any]?) {
|
||||
user = edited?["user"] as? String
|
||||
ts = edited?["ts"] as? String
|
||||
user = edited?[CodingKeys.user.rawValue] as? String
|
||||
ts = edited?[CodingKeys.ts.rawValue] as? String
|
||||
}
|
||||
}
|
||||
|
||||
extension Edited: Codable {
|
||||
public init(from decoder: Decoder) throws {
|
||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||
user = try values.decodeIfPresent(String.self, forKey: .user)
|
||||
ts = try values.decodeIfPresent(String.self, forKey: .ts)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(user, forKey: .user)
|
||||
try container.encode(ts, forKey: .ts)
|
||||
}
|
||||
}
|
||||
|
||||
extension Edited.CodingKeys: CodingKey { }
|
||||
|
||||
@@ -22,11 +22,32 @@
|
||||
// THE SOFTWARE.
|
||||
|
||||
public struct Reply {
|
||||
fileprivate enum CodingKeys: String {
|
||||
case user
|
||||
case ts
|
||||
}
|
||||
|
||||
public let user: String?
|
||||
public let ts: String?
|
||||
|
||||
|
||||
public init(reply: [String: Any]?) {
|
||||
user = reply?["user"] as? String
|
||||
ts = reply?["ts"] as? String
|
||||
user = reply?[CodingKeys.user.rawValue] as? String
|
||||
ts = reply?[CodingKeys.ts.rawValue] as? String
|
||||
}
|
||||
}
|
||||
|
||||
extension Reply: Codable {
|
||||
public init(from decoder: Decoder) throws {
|
||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||
user = try values.decodeIfPresent(String.self, forKey: .user)
|
||||
ts = try values.decodeIfPresent(String.self, forKey: .ts)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(user, forKey: .user)
|
||||
try container.encode(ts, forKey: .ts)
|
||||
}
|
||||
}
|
||||
|
||||
extension Reply.CodingKeys: CodingKey { }
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ let package = Package(
|
||||
targets: ["SampleApp"]),
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/pvzig/SlackKit.git", .upToNextMinor(from: "4.2.0")),
|
||||
.package(url: "https://github.com/pvzig/SlackKit.git", .upToNextMinor(from: "4.3.0")),
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ let package = Package(
|
||||
targets: ["SampleApp"]),
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/pvzig/SlackKit.git", .upToNextMinor(from: "4.2.0")),
|
||||
.package(url: "https://github.com/pvzig/SlackKit.git", .upToNextMinor(from: "4.3.0")),
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ let package = Package(
|
||||
targets: ["SampleApp"]),
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/pvzig/SlackKit.git", .upToNextMinor(from: "4.2.0")),
|
||||
.package(url: "https://github.com/pvzig/SlackKit.git", .upToNextMinor(from: "4.3.0")),
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
|
||||
@@ -88,6 +88,7 @@ public enum Endpoint: String {
|
||||
case usersGetPresence = "users.getPresence"
|
||||
case usersInfo = "users.info"
|
||||
case usersList = "users.list"
|
||||
case usersLookupByEmail = "users.lookupByEmail"
|
||||
case usersProfileSet = "users.profile.set"
|
||||
case usersSetActive = "users.setActive"
|
||||
case usersSetPresence = "users.setPresence"
|
||||
|
||||
@@ -271,6 +271,7 @@ extension WebAPI {
|
||||
parse: ParseMode? = nil,
|
||||
linkNames: Bool? = nil,
|
||||
attachments: [Attachment?]? = nil,
|
||||
blocks: [Block]? = nil,
|
||||
unfurlLinks: Bool? = nil,
|
||||
unfurlMedia: Bool? = nil,
|
||||
iconURL: String? = nil,
|
||||
@@ -290,7 +291,8 @@ extension WebAPI {
|
||||
"username": username,
|
||||
"icon_url": iconURL,
|
||||
"icon_emoji": iconEmoji,
|
||||
"attachments": encodeAttachments(attachments)
|
||||
"attachments": encodeAttachments(attachments),
|
||||
"blocks": encodeBlocks(blocks)
|
||||
]
|
||||
networkInterface.request(.chatPostMessage, parameters: parameters, successClosure: {(response) in
|
||||
success?((ts: response["ts"] as? String, response["channel"] as? String))
|
||||
@@ -346,6 +348,7 @@ extension WebAPI {
|
||||
thread: String? = nil,
|
||||
asUser: Bool? = nil,
|
||||
attachments: [Attachment?]? = nil,
|
||||
blocks: [Block]? = nil,
|
||||
linkNames: Bool? = nil,
|
||||
parse: ParseMode? = nil,
|
||||
success: (((ts: String?, channel: String?)) -> Void)?,
|
||||
@@ -359,6 +362,7 @@ extension WebAPI {
|
||||
"thread_ts": thread,
|
||||
"as_user": asUser,
|
||||
"attachments": encodeAttachments(attachments),
|
||||
"blocks": encodeBlocks(blocks),
|
||||
"link_names": linkNames,
|
||||
"parse": parse?.rawValue,
|
||||
]
|
||||
@@ -1134,6 +1138,15 @@ extension WebAPI {
|
||||
failure?(error)
|
||||
}
|
||||
}
|
||||
|
||||
public func usersLookupByEmail(_ email: String, success: ((_ user: User) -> Void)?, failure: FailureClosure?) {
|
||||
let parameters: [String: Any] = ["token": token, "email": email]
|
||||
networkInterface.request(.usersLookupByEmail, parameters: parameters, successClosure: { response in
|
||||
success?(User(user: response["user"] as? [String: Any]))
|
||||
}) { error in
|
||||
failure?(error)
|
||||
}
|
||||
}
|
||||
|
||||
public func usersProfileSet(profile: User.Profile, success: SuccessClosure?, failure: FailureClosure?) {
|
||||
let profileValues = ([
|
||||
@@ -1241,6 +1254,19 @@ extension WebAPI {
|
||||
return nil
|
||||
}
|
||||
|
||||
fileprivate func encodeBlocks(_ blocks: [Block]?) -> String? {
|
||||
if let blocks = blocks {
|
||||
let blocksArray: [[String: Any]] = blocks.map { $0.dictionary }
|
||||
do {
|
||||
let data = try JSONSerialization.data(withJSONObject: blocksArray, options: [])
|
||||
return String(data: data, encoding: String.Encoding.utf8)
|
||||
} catch let error {
|
||||
print(error)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
fileprivate func enumerateDNDStatuses(_ statuses: [String: Any]) -> [String: DoNotDisturbStatus] {
|
||||
var retVal = [String: DoNotDisturbStatus]()
|
||||
for key in statuses.keys {
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
2601B70C222F6CFD00F197AB /* SKClientTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2601B70B222F6CFD00F197AB /* SKClientTests.swift */; };
|
||||
2601B70F222F766D00F197AB /* member_joined_channel.json in Resources */ = {isa = PBXBuildFile; fileRef = 2601B70D222F766D00F197AB /* member_joined_channel.json */; };
|
||||
2601B710222F766D00F197AB /* member_left_channel.json in Resources */ = {isa = PBXBuildFile; fileRef = 2601B70E222F766D00F197AB /* member_left_channel.json */; };
|
||||
262F50412259145700A74EB1 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 262F503F2259145700A74EB1 /* main.swift */; };
|
||||
262F50422259145700A74EB1 /* Leaderbot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 262F50402259145700A74EB1 /* Leaderbot.swift */; };
|
||||
262F505B22591A6F00A74EB1 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 262F505A22591A6F00A74EB1 /* main.swift */; };
|
||||
263B102421FE33A000AF9EF9 /* UserGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 263B100921FE33A000AF9EF9 /* UserGroup.swift */; };
|
||||
263B102521FE33A000AF9EF9 /* Scope.swift in Sources */ = {isa = PBXBuildFile; fileRef = 263B100A21FE33A000AF9EF9 /* Scope.swift */; };
|
||||
263B102621FE33A000AF9EF9 /* AttachmentField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 263B100B21FE33A000AF9EF9 /* AttachmentField.swift */; };
|
||||
@@ -106,19 +109,23 @@
|
||||
263B10DF21FE548800AF9EF9 /* SKWebAPI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 263B0FB721FE23B000AF9EF9 /* SKWebAPI.framework */; };
|
||||
269A176A21FFDF9E00F1F500 /* Starscream.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 269A176021FFDB4C00F1F500 /* Starscream.framework */; };
|
||||
269A176D21FFDFB200F1F500 /* Swifter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 269A176121FFDB4C00F1F500 /* Swifter.framework */; };
|
||||
269A18342204055200F1F500 /* Leaderbot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 269A18322204055200F1F500 /* Leaderbot.swift */; };
|
||||
269A18352204055200F1F500 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 269A18332204055200F1F500 /* main.swift */; };
|
||||
269A185C220BB32B00F1F500 /* Starscream.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 269A175A21FFDB4C00F1F500 /* Starscream.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
269A185D220BB32B00F1F500 /* Swifter.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 269A175B21FFDB4C00F1F500 /* Swifter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
26D4E4D32210A31F00A67B67 /* Starscream.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 269A175A21FFDB4C00F1F500 /* Starscream.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
26D4E4D42210A31F00A67B67 /* Swifter.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 269A175B21FFDB4C00F1F500 /* Swifter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
26D4E4D92210A33A00A67B67 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 269A18362204057900F1F500 /* main.swift */; };
|
||||
26D4E605221211FD00A67B67 /* SlackKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 26D4E602221211B900A67B67 /* SlackKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
26D4E6062212120100A67B67 /* SKClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 26D4E5FF221211B900A67B67 /* SKClient.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
26D4E6072212120500A67B67 /* SKCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 26D4E603221211B900A67B67 /* SKCore.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
26D4E6082212120900A67B67 /* SKRTMAPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 26D4E5FE221211B900A67B67 /* SKRTMAPI.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
26D4E6092212120F00A67B67 /* SKServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 26D4E600221211B900A67B67 /* SKServer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
26D4E60A2212121400A67B67 /* SKWebAPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 26D4E601221211B900A67B67 /* SKWebAPI.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
A20D15EA22DE158000044CFC /* BlockComposition.swift in Sources */ = {isa = PBXBuildFile; fileRef = A20D15E722DE158000044CFC /* BlockComposition.swift */; };
|
||||
A20D15EB22DE158000044CFC /* BlockElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = A20D15E822DE158000044CFC /* BlockElement.swift */; };
|
||||
A20D15EC22DE158000044CFC /* BlockLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = A20D15E922DE158000044CFC /* BlockLayout.swift */; };
|
||||
9EA45FB922C01290006A6D36 /* action.json in Resources */ = {isa = PBXBuildFile; fileRef = 9EA45FB822C01290006A6D36 /* action.json */; };
|
||||
9EE6A7C322C2CDD6002BD111 /* edited.json in Resources */ = {isa = PBXBuildFile; fileRef = 9EE6A7C222C2CDD6002BD111 /* edited.json */; };
|
||||
9EEC459622BE63F800206AC3 /* reply.json in Resources */ = {isa = PBXBuildFile; fileRef = 9EEC459522BE63F800206AC3 /* reply.json */; };
|
||||
9EEC459822BE789600206AC3 /* attachmentfield.json in Resources */ = {isa = PBXBuildFile; fileRef = 9EEC459722BE789600206AC3 /* attachmentfield.json */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -197,6 +204,9 @@
|
||||
2601B70B222F6CFD00F197AB /* SKClientTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SKClientTests.swift; sourceTree = "<group>"; };
|
||||
2601B70D222F766D00F197AB /* member_joined_channel.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = member_joined_channel.json; sourceTree = "<group>"; };
|
||||
2601B70E222F766D00F197AB /* member_left_channel.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = member_left_channel.json; sourceTree = "<group>"; };
|
||||
262F503F2259145700A74EB1 /* main.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
|
||||
262F50402259145700A74EB1 /* Leaderbot.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Leaderbot.swift; sourceTree = "<group>"; };
|
||||
262F505A22591A6F00A74EB1 /* main.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = main.swift; path = "Examples/Robot Or Not Bot/Robot Or Not Bot/Sources/main.swift"; sourceTree = SOURCE_ROOT; };
|
||||
263B0F9B21FE235100AF9EF9 /* SKCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SKCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
263B0FAA21FE23A000AF9EF9 /* SKClient.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SKClient.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
263B0FB721FE23B000AF9EF9 /* SKWebAPI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SKWebAPI.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@@ -287,9 +297,6 @@
|
||||
269A176121FFDB4C00F1F500 /* Swifter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Swifter.framework; sourceTree = "<group>"; };
|
||||
269A177021FFE40700F1F500 /* SKRTMAPI.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = SKRTMAPI.xcconfig; sourceTree = "<group>"; };
|
||||
269A177121FFE4E200F1F500 /* SKServer.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = SKServer.xcconfig; sourceTree = "<group>"; };
|
||||
269A18322204055200F1F500 /* Leaderbot.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Leaderbot.swift; sourceTree = "<group>"; };
|
||||
269A18332204055200F1F500 /* main.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
|
||||
269A18362204057900F1F500 /* main.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
|
||||
26D4E4D82210A31F00A67B67 /* Robot or Not Bot.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Robot or Not Bot.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
26D4E5FE221211B900A67B67 /* SKRTMAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SKRTMAPI.h; sourceTree = "<group>"; };
|
||||
26D4E5FF221211B900A67B67 /* SKClient.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SKClient.h; sourceTree = "<group>"; };
|
||||
@@ -311,6 +318,13 @@
|
||||
26D4E6292220731800A67B67 /* rtm.connect.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = rtm.connect.json; sourceTree = "<group>"; };
|
||||
26D4E62A2220731800A67B67 /* file.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = file.json; sourceTree = "<group>"; };
|
||||
26D4E6362220733F00A67B67 /* SKCoreTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKCoreTests.swift; sourceTree = "<group>"; };
|
||||
A20D15E722DE158000044CFC /* BlockComposition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlockComposition.swift; sourceTree = "<group>"; };
|
||||
A20D15E822DE158000044CFC /* BlockElement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlockElement.swift; sourceTree = "<group>"; };
|
||||
A20D15E922DE158000044CFC /* BlockLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlockLayout.swift; sourceTree = "<group>"; };
|
||||
9EA45FB822C01290006A6D36 /* action.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = action.json; sourceTree = "<group>"; };
|
||||
9EE6A7C222C2CDD6002BD111 /* edited.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = edited.json; sourceTree = "<group>"; };
|
||||
9EEC459522BE63F800206AC3 /* reply.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = reply.json; sourceTree = "<group>"; };
|
||||
9EEC459722BE789600206AC3 /* attachmentfield.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = attachmentfield.json; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -393,6 +407,16 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
262F503E2259145700A74EB1 /* Sources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
262F503F2259145700A74EB1 /* main.swift */,
|
||||
262F50402259145700A74EB1 /* Leaderbot.swift */,
|
||||
);
|
||||
name = Sources;
|
||||
path = Leaderboard/Sources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
263B0F8121FE1B2300AF9EF9 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -484,6 +508,9 @@
|
||||
263B102221FE33A000AF9EF9 /* Action.swift */,
|
||||
263B100C21FE33A000AF9EF9 /* Attachment.swift */,
|
||||
263B100B21FE33A000AF9EF9 /* AttachmentField.swift */,
|
||||
A20D15E722DE158000044CFC /* BlockComposition.swift */,
|
||||
A20D15E822DE158000044CFC /* BlockElement.swift */,
|
||||
A20D15E922DE158000044CFC /* BlockLayout.swift */,
|
||||
263B101B21FE33A000AF9EF9 /* Bot.swift */,
|
||||
263B101521FE33A000AF9EF9 /* Channel.swift */,
|
||||
263B101021FE33A000AF9EF9 /* Comment.swift */,
|
||||
@@ -755,20 +782,11 @@
|
||||
269A18282204048300F1F500 /* Leaderboard */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
269A182A2204048300F1F500 /* Sources */,
|
||||
262F503E2259145700A74EB1 /* Sources */,
|
||||
);
|
||||
path = Leaderboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
269A182A2204048300F1F500 /* Sources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
269A18322204055200F1F500 /* Leaderbot.swift */,
|
||||
269A18332204055200F1F500 /* main.swift */,
|
||||
);
|
||||
path = Sources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
269A182C2204048300F1F500 /* Robot or Not Bot */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -780,7 +798,7 @@
|
||||
269A182D2204048300F1F500 /* Sources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
269A18362204057900F1F500 /* main.swift */,
|
||||
262F505A22591A6F00A74EB1 /* main.swift */,
|
||||
);
|
||||
path = Sources;
|
||||
sourceTree = "<group>";
|
||||
@@ -817,13 +835,17 @@
|
||||
26D4E618222072A700A67B67 /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9EA45FB822C01290006A6D36 /* action.json */,
|
||||
9EEC459722BE789600206AC3 /* attachmentfield.json */,
|
||||
26D4E6282220731800A67B67 /* channel.json */,
|
||||
26D4E6222220731700A67B67 /* conversation.json */,
|
||||
9EE6A7C222C2CDD6002BD111 /* edited.json */,
|
||||
26D4E6262220731800A67B67 /* events.json */,
|
||||
26D4E62A2220731800A67B67 /* file.json */,
|
||||
26D4E6272220731800A67B67 /* group.json */,
|
||||
26D4E6232220731700A67B67 /* im.json */,
|
||||
26D4E6212220731700A67B67 /* mpim.json */,
|
||||
9EEC459522BE63F800206AC3 /* reply.json */,
|
||||
26D4E6292220731800A67B67 /* rtm.connect.json */,
|
||||
26D4E6202220731700A67B67 /* rtm.start.json */,
|
||||
26D4E6242220731800A67B67 /* user.json */,
|
||||
@@ -1148,6 +1170,9 @@
|
||||
CreatedOnToolsVersion = 10.1;
|
||||
LastSwiftMigration = 1010;
|
||||
};
|
||||
26D4E4CB2210A31F00A67B67 = {
|
||||
LastSwiftMigration = 1020;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 263B0F8521FE1B2300AF9EF9 /* Build configuration list for PBXProject "SlackKit" */;
|
||||
@@ -1181,6 +1206,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2601B6CD2223038A00F197AB /* channel.json in Resources */,
|
||||
9EA45FB922C01290006A6D36 /* action.json in Resources */,
|
||||
2601B710222F766D00F197AB /* member_left_channel.json in Resources */,
|
||||
2601B6CE2223038A00F197AB /* conversation.json in Resources */,
|
||||
2601B70F222F766D00F197AB /* member_joined_channel.json in Resources */,
|
||||
@@ -1191,8 +1217,11 @@
|
||||
2601B6D32223038A00F197AB /* mpim.json in Resources */,
|
||||
2601B6D42223038A00F197AB /* rtm.connect.json in Resources */,
|
||||
2601B6D52223038A00F197AB /* rtm.start.json in Resources */,
|
||||
9EEC459822BE789600206AC3 /* attachmentfield.json in Resources */,
|
||||
2601B6D62223038A00F197AB /* user.json in Resources */,
|
||||
9EEC459622BE63F800206AC3 /* reply.json in Resources */,
|
||||
2601B6D72223038A00F197AB /* usergroup.json in Resources */,
|
||||
9EE6A7C322C2CDD6002BD111 /* edited.json in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -1258,6 +1287,8 @@
|
||||
263B103D21FE33A000AF9EF9 /* Action.swift in Sources */,
|
||||
263B102D21FE33A000AF9EF9 /* Item.swift in Sources */,
|
||||
263B103521FE33A000AF9EF9 /* Extensions.swift in Sources */,
|
||||
A20D15EA22DE158000044CFC /* BlockComposition.swift in Sources */,
|
||||
A20D15EB22DE158000044CFC /* BlockElement.swift in Sources */,
|
||||
263B103621FE33A000AF9EF9 /* Bot.swift in Sources */,
|
||||
263B102921FE33A000AF9EF9 /* Edited.swift in Sources */,
|
||||
263B102721FE33A000AF9EF9 /* Attachment.swift in Sources */,
|
||||
@@ -1265,6 +1296,7 @@
|
||||
263B103C21FE33A000AF9EF9 /* SlackError.swift in Sources */,
|
||||
263B103221FE33A000AF9EF9 /* Team.swift in Sources */,
|
||||
263B103321FE33A000AF9EF9 /* User.swift in Sources */,
|
||||
A20D15EC22DE158000044CFC /* BlockLayout.swift in Sources */,
|
||||
263B103021FE33A000AF9EF9 /* Channel.swift in Sources */,
|
||||
263B102621FE33A000AF9EF9 /* AttachmentField.swift in Sources */,
|
||||
263B102B21FE33A000AF9EF9 /* Comment.swift in Sources */,
|
||||
@@ -1367,8 +1399,8 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
269A18352204055200F1F500 /* main.swift in Sources */,
|
||||
269A18342204055200F1F500 /* Leaderbot.swift in Sources */,
|
||||
262F50422259145700A74EB1 /* Leaderbot.swift in Sources */,
|
||||
262F50412259145700A74EB1 /* main.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -1376,7 +1408,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
26D4E4D92210A33A00A67B67 /* main.swift in Sources */,
|
||||
262F505B22591A6F00A74EB1 /* main.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -2000,7 +2032,7 @@
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SDKROOT = macosx;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 4.2;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -2024,7 +2056,7 @@
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SDKROOT = macosx;
|
||||
SWIFT_VERSION = 4.2;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -2050,7 +2082,7 @@
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SDKROOT = macosx;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 4.2;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -2074,7 +2106,7 @@
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SDKROOT = macosx;
|
||||
SWIFT_VERSION = 4.2;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ Add SlackKit to your <code>Package.swift</code>
|
||||
```swift
|
||||
let package = Package(
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/pvzig/SlackKit.git", .upToNextMinor(from: "4.2.0"))
|
||||
.package(url: "https://github.com/pvzig/SlackKit.git", .upToNextMinor(from: "4.3.0"))
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "any name",
|
||||
"text": "any text",
|
||||
"type": "any type",
|
||||
"value": "any value",
|
||||
"url": "any url",
|
||||
"style": "primary",
|
||||
"confirm":
|
||||
{
|
||||
"title": "any title",
|
||||
"text": "any text",
|
||||
"ok_text": "any ok text",
|
||||
"dismiss_text": "any dismiss text"
|
||||
},
|
||||
"options":
|
||||
[
|
||||
{
|
||||
"text": "any text 1",
|
||||
"value": "any value 1"
|
||||
},
|
||||
{
|
||||
"text": "any text 2",
|
||||
"value": "any value 2"
|
||||
}
|
||||
],
|
||||
"data_source": "channels"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"title": "any title",
|
||||
"value": "any value",
|
||||
"short": false
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"user": "U0CJ5PC7L",
|
||||
"ts": "1448262357.000002"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"user": "U0CJ5PC7L",
|
||||
"ts": "1448262357.000002"
|
||||
}
|
||||
@@ -44,6 +44,10 @@ final class SKCoreTests: XCTestCase {
|
||||
static let user = try! Data(contentsOf: URL(fileURLWithPath: "\(rootPath)/user.json"))
|
||||
static let usergroup = try! Data(contentsOf: URL(fileURLWithPath: "\(rootPath)/usergroup.json"))
|
||||
static let events = try! Data(contentsOf: URL(fileURLWithPath: "\(rootPath)/events.json"))
|
||||
static let action = try! Data(contentsOf: URL(fileURLWithPath: "\(rootPath)/action.json"))
|
||||
static let attachmentfield = try! Data(contentsOf: URL(fileURLWithPath: "\(rootPath)/attachmentfield.json"))
|
||||
static let edited = try! Data(contentsOf: URL(fileURLWithPath: "\(rootPath)/edited.json"))
|
||||
static let reply = try! Data(contentsOf: URL(fileURLWithPath: "\(rootPath)/reply.json"))
|
||||
}
|
||||
|
||||
static var allTests = [
|
||||
@@ -55,7 +59,10 @@ final class SKCoreTests: XCTestCase {
|
||||
("TestMpim", testMpim),
|
||||
("testUser", testUser),
|
||||
("testUserGroup", testUserGroup),
|
||||
("testEvents", testEvents)
|
||||
("testEvents", testEvents),
|
||||
("testActionCodable", testActionCodable),
|
||||
("testAttachmentFieldCodable", testAttachmentFieldCodable),
|
||||
("testReplyCodable", testReplyCodable)
|
||||
]
|
||||
|
||||
func testEvents() {
|
||||
@@ -146,4 +153,87 @@ final class SKCoreTests: XCTestCase {
|
||||
let userGroup = UserGroup(userGroup: json)
|
||||
XCTAssertNotNil(userGroup)
|
||||
}
|
||||
|
||||
func testActionCodable() {
|
||||
let data = JSONData.action
|
||||
let decoder = JSONDecoder()
|
||||
let actionByDecoder = try? decoder.decode(Action.self, from: data)
|
||||
XCTAssertNotNil(actionByDecoder)
|
||||
XCTAssertNotNil(actionByDecoder!.name)
|
||||
XCTAssertNotNil(actionByDecoder!.text)
|
||||
XCTAssertNotNil(actionByDecoder!.type)
|
||||
XCTAssertNotNil(actionByDecoder!.value)
|
||||
XCTAssertNotNil(actionByDecoder!.url)
|
||||
XCTAssertNotNil(actionByDecoder!.style)
|
||||
XCTAssertNotNil(actionByDecoder!.confirm)
|
||||
XCTAssertNotNil(actionByDecoder!.options)
|
||||
XCTAssertNotNil(actionByDecoder!.dataSource)
|
||||
let encoder = JSONEncoder()
|
||||
let jsonData = try? encoder.encode(actionByDecoder!)
|
||||
XCTAssertNotNil(jsonData)
|
||||
let action = try? JSONSerialization.jsonObject(with: jsonData!, options: []) as? [String: Any]
|
||||
XCTAssertNotNil(action)
|
||||
let actionBySerialization = Action(action: action)
|
||||
XCTAssertEqual(actionBySerialization.name, actionByDecoder!.name)
|
||||
XCTAssertEqual(actionBySerialization.text, actionByDecoder!.text)
|
||||
XCTAssertEqual(actionBySerialization.type, actionByDecoder!.type)
|
||||
XCTAssertEqual(actionBySerialization.value, actionByDecoder!.value)
|
||||
XCTAssertEqual(actionBySerialization.url, actionByDecoder!.url)
|
||||
XCTAssertEqual(actionBySerialization.style, actionByDecoder!.style)
|
||||
XCTAssertEqual(actionBySerialization.options?.count, actionByDecoder!.options?.count)
|
||||
XCTAssertEqual(actionBySerialization.dataSource, actionByDecoder!.dataSource)
|
||||
}
|
||||
|
||||
func testAttachmentFieldCodable() {
|
||||
let data = JSONData.attachmentfield
|
||||
let decoder = JSONDecoder()
|
||||
let attachmentFieldByDecoder = try? decoder.decode(AttachmentField.self, from: data)
|
||||
XCTAssertNotNil(attachmentFieldByDecoder)
|
||||
XCTAssertNotNil(attachmentFieldByDecoder!.title)
|
||||
XCTAssertNotNil(attachmentFieldByDecoder!.value)
|
||||
XCTAssertNotNil(attachmentFieldByDecoder!.short)
|
||||
let encoder = JSONEncoder()
|
||||
let jsonData = try? encoder.encode(attachmentFieldByDecoder!)
|
||||
XCTAssertNotNil(jsonData)
|
||||
let field = try? JSONSerialization.jsonObject(with: jsonData!, options: []) as? [String: Any]
|
||||
XCTAssertNotNil(field)
|
||||
let attachmentFieldBySerialization = AttachmentField(field: field)
|
||||
XCTAssertEqual(attachmentFieldBySerialization.title, attachmentFieldByDecoder!.title)
|
||||
XCTAssertEqual(attachmentFieldBySerialization.value, attachmentFieldByDecoder!.value)
|
||||
XCTAssertEqual(attachmentFieldBySerialization.short, attachmentFieldByDecoder!.short)
|
||||
}
|
||||
|
||||
func testEditedCodable() {
|
||||
let data = JSONData.edited
|
||||
let decoder = JSONDecoder()
|
||||
let editedByDecoder = try? decoder.decode(Edited.self, from: data)
|
||||
XCTAssertNotNil(editedByDecoder)
|
||||
XCTAssertNotNil(editedByDecoder!.user)
|
||||
XCTAssertNotNil(editedByDecoder!.ts)
|
||||
let encoder = JSONEncoder()
|
||||
let jsonData = try? encoder.encode(editedByDecoder!)
|
||||
XCTAssertNotNil(jsonData)
|
||||
let edited = try? JSONSerialization.jsonObject(with: jsonData!, options: []) as? [String: Any]
|
||||
XCTAssertNotNil(edited)
|
||||
let editedBySerialization = Edited(edited: edited)
|
||||
XCTAssertEqual(editedBySerialization.user, editedByDecoder!.user)
|
||||
XCTAssertEqual(editedBySerialization.ts, editedByDecoder!.ts)
|
||||
}
|
||||
|
||||
func testReplyCodable() {
|
||||
let data = JSONData.reply
|
||||
let decoder = JSONDecoder()
|
||||
let replyByDecoder = try? decoder.decode(Reply.self, from: data)
|
||||
XCTAssertNotNil(replyByDecoder)
|
||||
XCTAssertNotNil(replyByDecoder!.user)
|
||||
XCTAssertNotNil(replyByDecoder!.ts)
|
||||
let encoder = JSONEncoder()
|
||||
let jsonData = try? encoder.encode(replyByDecoder!)
|
||||
XCTAssertNotNil(jsonData)
|
||||
let reply = try? JSONSerialization.jsonObject(with: jsonData!, options: []) as? [String: Any]
|
||||
XCTAssertNotNil(reply)
|
||||
let replyBySerialization = Reply(reply: reply)
|
||||
XCTAssertEqual(replyBySerialization.user, replyByDecoder!.user)
|
||||
XCTAssertEqual(replyBySerialization.ts, replyByDecoder!.ts)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,10 @@ extension SKCoreTests {
|
||||
("testMpim", testMpim),
|
||||
("testUser", testUser),
|
||||
("testUserGroup", testUserGroup),
|
||||
("testActionCodable", testActionCodable),
|
||||
("testAttachmentFieldCodable", testAttachmentFieldCodable),
|
||||
("testEditedCodable", testEditedCodable),
|
||||
("testReplyCodable", testReplyCodable),
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
+15
-15
@@ -10,7 +10,7 @@ jobs:
|
||||
# Builds
|
||||
- job: macOS
|
||||
pool:
|
||||
vmImage: 'macOS-10.13'
|
||||
vmImage: 'macOS-10.14'
|
||||
steps:
|
||||
- task: Xcode@5
|
||||
inputs:
|
||||
@@ -18,19 +18,19 @@ jobs:
|
||||
scheme: 'SlackKit'
|
||||
sdk: 'macosx'
|
||||
configuration: 'Release'
|
||||
xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace'
|
||||
xcodeVersion: '10'
|
||||
xcWorkspacePath: 'SlackKit.xcodeproj/project.xcworkspace'
|
||||
xcodeVersion: 'default'
|
||||
- task: Xcode@5
|
||||
inputs:
|
||||
actions: 'test'
|
||||
scheme: 'SlackKitTests'
|
||||
sdk: 'macosx'
|
||||
configuration: 'Debug'
|
||||
xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace'
|
||||
xcodeVersion: '10'
|
||||
xcWorkspacePath: 'SlackKit.xcodeproj/project.xcworkspace'
|
||||
xcodeVersion: 'default'
|
||||
- job: iOS
|
||||
pool:
|
||||
vmImage: 'macOS-10.13'
|
||||
vmImage: 'macOS-10.14'
|
||||
steps:
|
||||
- task: Xcode@5
|
||||
inputs:
|
||||
@@ -38,19 +38,19 @@ jobs:
|
||||
scheme: 'SlackKit'
|
||||
sdk: 'iphoneos'
|
||||
configuration: 'Release'
|
||||
xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace'
|
||||
xcodeVersion: '10'
|
||||
xcWorkspacePath: 'SlackKit.xcodeproj/project.xcworkspace'
|
||||
xcodeVersion: 'default'
|
||||
- task: Xcode@5
|
||||
inputs:
|
||||
actions: 'test'
|
||||
scheme: 'SlackKitTests'
|
||||
sdk: 'iphonesimulator'
|
||||
configuration: 'Debug'
|
||||
xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace'
|
||||
xcodeVersion: '10'
|
||||
xcWorkspacePath: 'SlackKit.xcodeproj/project.xcworkspace'
|
||||
xcodeVersion: 'default'
|
||||
- job: tvOS
|
||||
pool:
|
||||
vmImage: 'macOS-10.13'
|
||||
vmImage: 'macOS-10.14'
|
||||
steps:
|
||||
- task: Xcode@5
|
||||
inputs:
|
||||
@@ -58,16 +58,16 @@ jobs:
|
||||
scheme: 'SlackKit'
|
||||
sdk: 'appletvos'
|
||||
configuration: 'Release'
|
||||
xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace'
|
||||
xcodeVersion: '10'
|
||||
xcWorkspacePath: 'SlackKit.xcodeproj/project.xcworkspace'
|
||||
xcodeVersion: 'default'
|
||||
- task: Xcode@5
|
||||
inputs:
|
||||
actions: 'test'
|
||||
scheme: 'SlackKitTests'
|
||||
sdk: 'appletvsimulator'
|
||||
configuration: 'Debug'
|
||||
xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace'
|
||||
xcodeVersion: '10'
|
||||
xcWorkspacePath: 'SlackKit.xcodeproj/project.xcworkspace'
|
||||
xcodeVersion: 'default'
|
||||
- job: Linux
|
||||
pool:
|
||||
vmImage: 'ubuntu-16.04'
|
||||
|
||||
Reference in New Issue
Block a user