Compare commits

...

33 Commits

Author SHA1 Message Date
Peter Zignego 267cf26b2e Merge pull request #165 from vasilenkoigor/UsersLookupByEmail-Endpoint
Added missed users.lookupByEmail endpoint
2019-07-25 21:20:42 -04:00
i.v.vasilenko c3817bea15 Added missed parameter for users.lookupByEmail endpoint 2019-07-21 21:53:30 +03:00
i.v.vasilenko 492f51ce9b Added missed endpoint users.lookupByEmail 2019-07-21 21:33:38 +03:00
Peter Zignego dd72c619d3 Merge pull request #164 from RobotsAndPencils/add_block_support
Adding Blocks support
2019-07-17 09:50:25 -04:00
Peter Zignego 43af10de88 Merge branch 'master' into add_block_support 2019-07-17 09:43:55 -04:00
Brad Brown 7ba97e4893 Adding Blocks support 2019-07-16 09:26:14 -05:00
Peter Zignego 0c24cb2262 Merge pull request #163 from RomanPodymov/master
Action, AttachmentField, Edited and Reply conform to Codable
2019-07-12 10:30:23 -04:00
Roman Podymov 7b76b76b94 Update XCTestManifests.swift 2019-06-26 00:33:52 +02:00
Roman Podymov 565c44677b Update XCTestManifests.swift 2019-06-26 00:33:38 +02:00
Roman Podymov 30dc3679c1 Fixed tests 2019-06-26 00:26:19 +02:00
Roman Podymov 9a18cae265 removed \n 2019-06-23 22:39:44 +02:00
Roman Podymov c04654a87b tests for Action 2019-06-23 22:38:45 +02:00
Roman Podymov bd7f67b3b0 attachmentfield tests 2019-06-22 17:03:01 +02:00
Roman Podymov 833add707f removed \n 2019-06-22 16:49:28 +02:00
Roman Podymov 9118a7688a tests for Reply (added missing files) 2019-06-22 16:46:36 +02:00
Roman Podymov cba1eb36a2 Tests for Reply 2019-06-22 16:45:11 +02:00
Roman Podymov d15139d00d Update Reply.swift 2019-06-22 14:53:35 +02:00
Roman Podymov c1cf9b47d8 Update AttachmentField.swift 2019-06-22 14:49:43 +02:00
Roman Podymov 986367be38 Update Action.swift 2019-06-22 14:48:08 +02:00
Peter Zignego 7d207136b3 Merge pull request #162 from pvzig/ci-update
Update to Azure Pipelines to macOS 10.14 and Xcode 10.2
2019-04-11 20:40:16 -04:00
Peter Zignego 0fa3b72a56 Workspace path 2019-04-11 20:36:18 -04:00
Peter Zignego 67d2bb3f62 xcodeVersion 2019-04-11 20:08:26 -04:00
Peter Zignego f2c333f57d Update to macOS 10.14 and Xcode 10.2 2019-04-11 20:01:40 -04:00
Peter Zignego eccda7a525 Merge pull request #161 from victorgama/fix/typo
Fix typo SKRMTAPI -> SKRTMAPI
2019-04-06 20:58:16 -04:00
Victor Gama ac0d9977b5 Fix typo SKRMTAPI -> SKRTMAPI 2019-04-06 20:29:34 -03:00
Peter Zignego 6c1612f2bb Merge pull request #160 from pvzig/examples
Support CocoaPods and Carthage for examples
2019-04-06 13:52:38 -04:00
Peter Zignego ead9bb9c41 Support CocoaPods and Carthage for examples 2019-04-06 13:46:27 -04:00
Peter Zignego cc20c54967 Update README.md 2019-04-05 11:29:39 -04:00
Peter Zignego d5c2dd48f7 Update README.md 2019-04-05 11:29:21 -04:00
Peter Zignego f4336f1dde Update README.md 2019-04-05 11:29:06 -04:00
Peter Zignego 7ab91d9440 Update README.md 2019-04-05 11:28:30 -04:00
Peter Zignego 7e7a168806 Update README.md 2019-04-05 11:27:59 -04:00
Peter Zignego 9651351ec9 Update README.md 2019-04-05 11:25:58 -04:00
41 changed files with 1698 additions and 104 deletions
+1
View File
@@ -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 */;
}
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Leaderboard.xcodeproj">
</FileRef>
</Workspace>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -0,0 +1,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,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:
+3 -3
View File
@@ -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")
]
)
+6
View File
@@ -0,0 +1,6 @@
platform :osx, '10.11'
target 'Leaderboard' do
use_frameworks!
pod 'SlackKit', '>= 4.3.0'
end
+1
View File
@@ -0,0 +1 @@
github "pvzig/SlackKit"
+2 -2
View File
@@ -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")
]
)
+7
View File
@@ -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 */;
}
@@ -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>
@@ -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
View File
@@ -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 -2
View File
@@ -2,7 +2,7 @@
[![Build Status](https://dev.azure.com/pzignego/SlackKit/_apis/build/status/pvzig.SlackKit?branchName=master)](https://dev.azure.com/pzignego/SlackKit/_build/latest?definitionId=2&branchName=master)
![Swift Version](https://img.shields.io/badge/Swift-4.2-orange.svg)
![Swift Version](https://img.shields.io/badge/Swift-5-orange.svg)
![Plaforms](https://img.shields.io/badge/Platforms-macOS,_iOS,_tvOS,_Linux-lightgrey.svg)
![License MIT](https://img.shields.io/badge/License-MIT-lightgrey.svg)
[![SwiftPM compatible](https://img.shields.io/badge/SwiftPM-compatible-brightgreen.svg)](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
View File
@@ -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
View File
@@ -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"
}
+31 -7
View File
@@ -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 { }
+96
View File
@@ -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
}
}
+354
View File
@@ -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
}
}
+156
View File
@@ -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
}
}
+23 -2
View File
@@ -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 { }
+24 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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(
+1
View File
@@ -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"
+27 -1
View File
@@ -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 {
+56 -24
View File
@@ -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
View File
@@ -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"))
]
)
```
+27
View File
@@ -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
}
+4
View File
@@ -0,0 +1,4 @@
{
"user": "U0CJ5PC7L",
"ts": "1448262357.000002"
}
+4
View File
@@ -0,0 +1,4 @@
{
"user": "U0CJ5PC7L",
"ts": "1448262357.000002"
}
+91 -1
View File
@@ -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)
}
}
+4
View File
@@ -18,6 +18,10 @@ extension SKCoreTests {
("testMpim", testMpim),
("testUser", testUser),
("testUserGroup", testUserGroup),
("testActionCodable", testActionCodable),
("testAttachmentFieldCodable", testAttachmentFieldCodable),
("testEditedCodable", testEditedCodable),
("testReplyCodable", testReplyCodable),
]
}
+15 -15
View File
@@ -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'