init
This commit is contained in:
commit
4cc1b4cca5
|
@ -0,0 +1 @@
|
|||
LICENSE BE HERE
|
|
@ -0,0 +1,138 @@
|
|||
#
|
||||
# Be sure to run `pod spec lint PSCBOnline.podspec' to ensure this is a
|
||||
# valid spec and to remove all comments including this before submitting the spec.
|
||||
#
|
||||
# To learn more about Podspec attributes see https://guides.cocoapods.org/syntax/podspec.html
|
||||
# To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
|
||||
#
|
||||
|
||||
Pod::Spec.new do |spec|
|
||||
|
||||
# ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
|
||||
#
|
||||
# These will help people to find your library, and whilst it
|
||||
# can feel like a chore to fill in it's definitely to your advantage. The
|
||||
# summary should be tweet-length, and the description more in depth.
|
||||
#
|
||||
|
||||
spec.name = "PSCBOnline"
|
||||
spec.version = "1.0.1"
|
||||
spec.summary = "An iOS SDK for PSCB Online (OOS) acquiring protocol."
|
||||
|
||||
# This description is used to generate tags and improve search results.
|
||||
# * Think: What does it do? Why did you write it? What is the focus?
|
||||
# * Try to keep it short, snappy and to the point.
|
||||
# * Write the description between the DESC delimiters below.
|
||||
# * Finally, don't worry about the indent, CocoaPods strips it!
|
||||
spec.description = "An implementation of PSCB-Online (oos.pscb.ru) acquiring protocol for iOS platforms."
|
||||
|
||||
spec.homepage = "https://oos.pscb.ru/"
|
||||
# spec.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"
|
||||
|
||||
|
||||
# ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
|
||||
#
|
||||
# Licensing your code is important. See https://choosealicense.com for more info.
|
||||
# CocoaPods will detect a license file if there is a named LICENSE*
|
||||
# Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
|
||||
#
|
||||
|
||||
spec.license = { :type => "PSCB", :file => "LICENSE.txt" }
|
||||
# spec.license = { :type => "MIT", :file => "FILE_LICENSE" }
|
||||
|
||||
|
||||
# ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
|
||||
#
|
||||
# Specify the authors of the library, with email addresses. Email addresses
|
||||
# of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also
|
||||
# accepts just a name if you'd rather not provide an email address.
|
||||
#
|
||||
# Specify a social_media_url where others can refer to, for example a twitter
|
||||
# profile URL.
|
||||
#
|
||||
|
||||
spec.authors = { "Antonov Ilia" => "antilya@gmail.com" }
|
||||
|
||||
# ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
|
||||
#
|
||||
# If this Pod runs only on iOS or OS X, then specify the platform and
|
||||
# the deployment target. You can optionally include the target after the platform.
|
||||
#
|
||||
|
||||
# spec.platform = :ios
|
||||
spec.platform = :ios, "10.0"
|
||||
|
||||
# When using multiple platforms
|
||||
spec.ios.deployment_target = "10.0"
|
||||
# spec.osx.deployment_target = "10.7"
|
||||
# spec.watchos.deployment_target = "2.0"
|
||||
# spec.tvos.deployment_target = "9.0"
|
||||
|
||||
|
||||
# ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
|
||||
#
|
||||
# Specify the location from where the source should be retrieved.
|
||||
# Supports git, hg, bzr, svn and HTTP.
|
||||
#
|
||||
|
||||
#spec.source = { :git => "http://EXAMPLE/PSCB_OOS.git", :tag => "#{spec.version}" }
|
||||
spec.source = { :git => "https://bitbucket.org/dev_ai/oos-ios.git", :tag => "#{spec.version}" }
|
||||
|
||||
|
||||
# ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
|
||||
#
|
||||
# CocoaPods is smart about how it includes source code. For source files
|
||||
# giving a folder will include any swift, h, m, mm, c & cpp files.
|
||||
# For header files it will include any header in the folder.
|
||||
# Not including the public_header_files will make all headers public.
|
||||
#
|
||||
|
||||
#spec.source_files = "PSCBOnline", "PSCBOnline/**/*.{h,m,swift}", "PSCBOnline/Sources/**/*.{h,m,swift}"
|
||||
spec.source_files = "PSCBOnline/**/*.{h,m,swift}"
|
||||
# spec.source_files = "PSCB-OOS-iOS", "PSCB-OOS-iOS/**/*.{h,m}"
|
||||
spec.exclude_files = ""
|
||||
|
||||
# spec.public_header_files = "Classes/**/*.h"
|
||||
|
||||
|
||||
# ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
|
||||
#
|
||||
# A list of resources included with the Pod. These are copied into the
|
||||
# target bundle with a build phase script. Anything else will be cleaned.
|
||||
# You can preserve files from being cleaned, please don't preserve
|
||||
# non-essential files like tests, examples and documentation.
|
||||
#
|
||||
|
||||
# spec.resource = "icon.png"
|
||||
# spec.resources = "Resources/*.png"
|
||||
|
||||
# spec.preserve_paths = "FilesToSave", "MoreFilesToSave"
|
||||
|
||||
|
||||
# ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
|
||||
#
|
||||
# Link your library with frameworks, or libraries. Libraries do not include
|
||||
# the lib prefix of their name.
|
||||
#
|
||||
|
||||
# spec.framework = "SomeFramework"
|
||||
# spec.frameworks = "SomeFramework", "AnotherFramework"
|
||||
|
||||
# spec.library = "iconv"
|
||||
# spec.libraries = "iconv", "xml2"
|
||||
|
||||
|
||||
# ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
|
||||
#
|
||||
# If your library depends on compiler flags you can set them in the xcconfig hash
|
||||
# where they will only apply to your library. If you depend on other Podspecs
|
||||
# you can include multiple dependencies to ensure it works.
|
||||
|
||||
# spec.requires_arc = true
|
||||
|
||||
# spec.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
|
||||
# spec.dependency "JSONKit", "~> 1.4"
|
||||
|
||||
spec.swift_version = "5.3"
|
||||
|
||||
end
|
|
@ -0,0 +1,652 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 50;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
0E01EAB425399CB500B0759B /* PSCBOnline.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E01EAAA25399CB500B0759B /* PSCBOnline.framework */; };
|
||||
0E01EAB925399CB500B0759B /* PSCBOnlineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E01EAB825399CB500B0759B /* PSCBOnlineTests.swift */; };
|
||||
0E01EABB25399CB500B0759B /* PSCBOnline.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E01EAAD25399CB500B0759B /* PSCBOnline.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
0E01EACD25399DB000B0759B /* Payment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E01EACC25399DB000B0759B /* Payment.swift */; };
|
||||
0E01EAD325399DF600B0759B /* CustomerData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E01EAD225399DF500B0759B /* CustomerData.swift */; };
|
||||
0E01EAD825399E3D00B0759B /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E01EAD725399E3D00B0759B /* String.swift */; };
|
||||
0E01EADE25399E8800B0759B /* RequestWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E01EADD25399E8800B0759B /* RequestWrapper.swift */; };
|
||||
0E01EAE425399EE800B0759B /* PaymentTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E01EAE325399EE800B0759B /* PaymentTests.swift */; };
|
||||
0E0A2C1F25408AA1006BBBA1 /* CardData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E0A2C1E25408AA1006BBBA1 /* CardData.swift */; };
|
||||
0E0A2C23254093D0006BBBA1 /* Payment+Serializable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E0A2C22254093D0006BBBA1 /* Payment+Serializable.swift */; };
|
||||
0E26F5862542FB5800F80DAC /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E26F5852542FB5800F80DAC /* Response.swift */; };
|
||||
0E26F58A2542FE2000F80DAC /* ResponseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E26F5892542FE2000F80DAC /* ResponseTests.swift */; };
|
||||
0E26F58F2545AE5800F80DAC /* JSONDecoders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E26F58E2545AE5800F80DAC /* JSONDecoders.swift */; };
|
||||
0E26F59F2547097300F80DAC /* RSAHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E26F59E2547097300F80DAC /* RSAHelper.swift */; };
|
||||
0E26F5A3254714B600F80DAC /* CardDataTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E26F5A2254714B600F80DAC /* CardDataTests.swift */; };
|
||||
0E26F5E82548717B00F80DAC /* PSCBAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E26F5E72548717B00F80DAC /* PSCBAPI.swift */; };
|
||||
0E26F62E2549591E00F80DAC /* DigestHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E26F62D2549591D00F80DAC /* DigestHelper.swift */; };
|
||||
0E26F63325495A5B00F80DAC /* DigestHelperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E26F63225495A5B00F80DAC /* DigestHelperTests.swift */; };
|
||||
0E790FA3253DEA930086AD71 /* PSCBOnline.podspec in Resources */ = {isa = PBXBuildFile; fileRef = 0E790FA2253DEA930086AD71 /* PSCBOnline.podspec */; };
|
||||
0E790FAB253E017E0086AD71 /* LICENSE.txt in Resources */ = {isa = PBXBuildFile; fileRef = 0E790FAA253E017E0086AD71 /* LICENSE.txt */; };
|
||||
0EA2C84E2539A5BA00C5DD14 /* Serializable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA2C84D2539A5BA00C5DD14 /* Serializable.swift */; };
|
||||
0EA2C8582539F4D500C5DD14 /* PSCBOnlineClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA2C8572539F4D500C5DD14 /* PSCBOnlineClient.swift */; };
|
||||
0EA2C8622539FAC200C5DD14 /* PaymentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA2C8612539FAC200C5DD14 /* PaymentHandler.swift */; };
|
||||
0EA2C86A253B29A900C5DD14 /* PKPaymentToken+Serializable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA2C869253B29A900C5DD14 /* PKPaymentToken+Serializable.swift */; };
|
||||
0EA2C872253CC44A00C5DD14 /* RequestWrapper+Serializable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA2C871253CC44A00C5DD14 /* RequestWrapper+Serializable.swift */; };
|
||||
0EC9DB072540A1C8005392A0 /* OOSAPIClientTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC9DB062540A1C8005392A0 /* OOSAPIClientTests.swift */; };
|
||||
0EC9DB0C2541B699005392A0 /* PassKitMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC9DB0B2541B699005392A0 /* PassKitMocks.swift */; };
|
||||
0EC9DB132541BF45005392A0 /* PKPaymentToken+SerializableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC9DB122541BF45005392A0 /* PKPaymentToken+SerializableTests.swift */; };
|
||||
0EC9DB192541D9F9005392A0 /* PKPaymentTokenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC9DB182541D9F9005392A0 /* PKPaymentTokenTests.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
0E01EAB525399CB500B0759B /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 0E01EAA125399CB500B0759B /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 0E01EAA925399CB500B0759B;
|
||||
remoteInfo = "PSCB-OOS-iOS";
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
0E01EAAA25399CB500B0759B /* PSCBOnline.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PSCBOnline.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0E01EAAD25399CB500B0759B /* PSCBOnline.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PSCBOnline.h; sourceTree = "<group>"; };
|
||||
0E01EAAE25399CB500B0759B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
0E01EAB325399CB500B0759B /* PSCBOnlineTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PSCBOnlineTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0E01EAB825399CB500B0759B /* PSCBOnlineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PSCBOnlineTests.swift; sourceTree = "<group>"; };
|
||||
0E01EABA25399CB500B0759B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
0E01EACC25399DB000B0759B /* Payment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Payment.swift; sourceTree = "<group>"; };
|
||||
0E01EAD225399DF500B0759B /* CustomerData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomerData.swift; sourceTree = "<group>"; };
|
||||
0E01EAD725399E3D00B0759B /* String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = "<group>"; };
|
||||
0E01EADD25399E8800B0759B /* RequestWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestWrapper.swift; sourceTree = "<group>"; };
|
||||
0E01EAE325399EE800B0759B /* PaymentTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentTests.swift; sourceTree = "<group>"; };
|
||||
0E0A2C1E25408AA1006BBBA1 /* CardData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardData.swift; sourceTree = "<group>"; };
|
||||
0E0A2C22254093D0006BBBA1 /* Payment+Serializable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Payment+Serializable.swift"; sourceTree = "<group>"; };
|
||||
0E26F5852542FB5800F80DAC /* Response.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Response.swift; sourceTree = "<group>"; };
|
||||
0E26F5892542FE2000F80DAC /* ResponseTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResponseTests.swift; sourceTree = "<group>"; };
|
||||
0E26F58E2545AE5800F80DAC /* JSONDecoders.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONDecoders.swift; sourceTree = "<group>"; };
|
||||
0E26F59E2547097300F80DAC /* RSAHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RSAHelper.swift; sourceTree = "<group>"; };
|
||||
0E26F5A2254714B600F80DAC /* CardDataTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardDataTests.swift; sourceTree = "<group>"; };
|
||||
0E26F5E72548717B00F80DAC /* PSCBAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PSCBAPI.swift; sourceTree = "<group>"; };
|
||||
0E26F62D2549591D00F80DAC /* DigestHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigestHelper.swift; sourceTree = "<group>"; };
|
||||
0E26F63225495A5B00F80DAC /* DigestHelperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigestHelperTests.swift; sourceTree = "<group>"; };
|
||||
0E547EB32552BEA500E0F8C0 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
||||
0E790FA2253DEA930086AD71 /* PSCBOnline.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PSCBOnline.podspec; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
|
||||
0E790FAA253E017E0086AD71 /* LICENSE.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE.txt; sourceTree = "<group>"; };
|
||||
0EA2C84D2539A5BA00C5DD14 /* Serializable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Serializable.swift; sourceTree = "<group>"; };
|
||||
0EA2C8572539F4D500C5DD14 /* PSCBOnlineClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PSCBOnlineClient.swift; sourceTree = "<group>"; };
|
||||
0EA2C8612539FAC200C5DD14 /* PaymentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentHandler.swift; sourceTree = "<group>"; };
|
||||
0EA2C869253B29A900C5DD14 /* PKPaymentToken+Serializable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PKPaymentToken+Serializable.swift"; sourceTree = "<group>"; };
|
||||
0EA2C871253CC44A00C5DD14 /* RequestWrapper+Serializable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RequestWrapper+Serializable.swift"; sourceTree = "<group>"; };
|
||||
0EC9DB062540A1C8005392A0 /* OOSAPIClientTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OOSAPIClientTests.swift; sourceTree = "<group>"; };
|
||||
0EC9DB0B2541B699005392A0 /* PassKitMocks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PassKitMocks.swift; sourceTree = "<group>"; };
|
||||
0EC9DB122541BF45005392A0 /* PKPaymentToken+SerializableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PKPaymentToken+SerializableTests.swift"; sourceTree = "<group>"; };
|
||||
0EC9DB182541D9F9005392A0 /* PKPaymentTokenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PKPaymentTokenTests.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
0E01EAA725399CB500B0759B /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
0E01EAB025399CB500B0759B /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0E01EAB425399CB500B0759B /* PSCBOnline.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
0E01EAA025399CB500B0759B = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0E547EB32552BEA500E0F8C0 /* README.md */,
|
||||
0E790FAA253E017E0086AD71 /* LICENSE.txt */,
|
||||
0E790FA2253DEA930086AD71 /* PSCBOnline.podspec */,
|
||||
0E01EAAC25399CB500B0759B /* PSCBOnline */,
|
||||
0E01EAB725399CB500B0759B /* PSCBOnlineTests */,
|
||||
0E01EAAB25399CB500B0759B /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0E01EAAB25399CB500B0759B /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0E01EAAA25399CB500B0759B /* PSCBOnline.framework */,
|
||||
0E01EAB325399CB500B0759B /* PSCBOnlineTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0E01EAAC25399CB500B0759B /* PSCBOnline */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0E01EAC625399CEF00B0759B /* Sources */,
|
||||
0E01EAAD25399CB500B0759B /* PSCBOnline.h */,
|
||||
0E01EAAE25399CB500B0759B /* Info.plist */,
|
||||
);
|
||||
path = PSCBOnline;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0E01EAB725399CB500B0759B /* PSCBOnlineTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0E26F63125495A2F00F80DAC /* Helpers */,
|
||||
0EC9DB112541BF2D005392A0 /* Serializable */,
|
||||
0EC9DB0A2541B686005392A0 /* Mocks */,
|
||||
0E01EAE125399ECE00B0759B /* Sources */,
|
||||
0E01EAB825399CB500B0759B /* PSCBOnlineTests.swift */,
|
||||
0E01EABA25399CB500B0759B /* Info.plist */,
|
||||
);
|
||||
path = PSCBOnlineTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0E01EAC625399CEF00B0759B /* Sources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0E26F58D2545AE4200F80DAC /* Helpers */,
|
||||
0EA2C84C2539A5A300C5DD14 /* Serializable */,
|
||||
0E01EAD625399E0F00B0759B /* Extension */,
|
||||
0E01EACB25399D8F00B0759B /* Models */,
|
||||
0EA2C8572539F4D500C5DD14 /* PSCBOnlineClient.swift */,
|
||||
0EA2C8612539FAC200C5DD14 /* PaymentHandler.swift */,
|
||||
0E26F5E72548717B00F80DAC /* PSCBAPI.swift */,
|
||||
);
|
||||
path = Sources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0E01EACB25399D8F00B0759B /* Models */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0E01EACC25399DB000B0759B /* Payment.swift */,
|
||||
0E01EAD225399DF500B0759B /* CustomerData.swift */,
|
||||
0E01EADD25399E8800B0759B /* RequestWrapper.swift */,
|
||||
0E0A2C1E25408AA1006BBBA1 /* CardData.swift */,
|
||||
0E26F5852542FB5800F80DAC /* Response.swift */,
|
||||
);
|
||||
path = Models;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0E01EAD625399E0F00B0759B /* Extension */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0E01EAD725399E3D00B0759B /* String.swift */,
|
||||
);
|
||||
path = Extension;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0E01EAE125399ECE00B0759B /* Sources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0E01EAE225399ED400B0759B /* Models */,
|
||||
0EC9DB062540A1C8005392A0 /* OOSAPIClientTests.swift */,
|
||||
);
|
||||
path = Sources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0E01EAE225399ED400B0759B /* Models */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0E01EAE325399EE800B0759B /* PaymentTests.swift */,
|
||||
0E26F5892542FE2000F80DAC /* ResponseTests.swift */,
|
||||
0E26F5A2254714B600F80DAC /* CardDataTests.swift */,
|
||||
);
|
||||
path = Models;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0E26F58D2545AE4200F80DAC /* Helpers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0E26F58E2545AE5800F80DAC /* JSONDecoders.swift */,
|
||||
0E26F59E2547097300F80DAC /* RSAHelper.swift */,
|
||||
0E26F62D2549591D00F80DAC /* DigestHelper.swift */,
|
||||
);
|
||||
path = Helpers;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0E26F63125495A2F00F80DAC /* Helpers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0E26F63225495A5B00F80DAC /* DigestHelperTests.swift */,
|
||||
);
|
||||
path = Helpers;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0EA2C84C2539A5A300C5DD14 /* Serializable */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0EA2C84D2539A5BA00C5DD14 /* Serializable.swift */,
|
||||
0EA2C869253B29A900C5DD14 /* PKPaymentToken+Serializable.swift */,
|
||||
0EA2C871253CC44A00C5DD14 /* RequestWrapper+Serializable.swift */,
|
||||
0E0A2C22254093D0006BBBA1 /* Payment+Serializable.swift */,
|
||||
);
|
||||
path = Serializable;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0EC9DB0A2541B686005392A0 /* Mocks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0EC9DB0B2541B699005392A0 /* PassKitMocks.swift */,
|
||||
);
|
||||
path = Mocks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0EC9DB112541BF2D005392A0 /* Serializable */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0EC9DB122541BF45005392A0 /* PKPaymentToken+SerializableTests.swift */,
|
||||
0EC9DB182541D9F9005392A0 /* PKPaymentTokenTests.swift */,
|
||||
);
|
||||
path = Serializable;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
0E01EAA525399CB500B0759B /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0E01EABB25399CB500B0759B /* PSCBOnline.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
0E01EAA925399CB500B0759B /* PSCBOnline */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 0E01EABE25399CB500B0759B /* Build configuration list for PBXNativeTarget "PSCBOnline" */;
|
||||
buildPhases = (
|
||||
0E01EAA525399CB500B0759B /* Headers */,
|
||||
0E01EAA625399CB500B0759B /* Sources */,
|
||||
0E01EAA725399CB500B0759B /* Frameworks */,
|
||||
0E01EAA825399CB500B0759B /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = PSCBOnline;
|
||||
productName = "PSCB-OOS-iOS";
|
||||
productReference = 0E01EAAA25399CB500B0759B /* PSCBOnline.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
0E01EAB225399CB500B0759B /* PSCBOnlineTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 0E01EAC125399CB500B0759B /* Build configuration list for PBXNativeTarget "PSCBOnlineTests" */;
|
||||
buildPhases = (
|
||||
0E01EAAF25399CB500B0759B /* Sources */,
|
||||
0E01EAB025399CB500B0759B /* Frameworks */,
|
||||
0E01EAB125399CB500B0759B /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
0E01EAB625399CB500B0759B /* PBXTargetDependency */,
|
||||
);
|
||||
name = PSCBOnlineTests;
|
||||
productName = "PSCB-OOS-iOSTests";
|
||||
productReference = 0E01EAB325399CB500B0759B /* PSCBOnlineTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
0E01EAA125399CB500B0759B /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 1200;
|
||||
LastUpgradeCheck = 1200;
|
||||
TargetAttributes = {
|
||||
0E01EAA925399CB500B0759B = {
|
||||
CreatedOnToolsVersion = 12.0.1;
|
||||
LastSwiftMigration = 1200;
|
||||
};
|
||||
0E01EAB225399CB500B0759B = {
|
||||
CreatedOnToolsVersion = 12.0.1;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 0E01EAA425399CB500B0759B /* Build configuration list for PBXProject "PSCBOnline" */;
|
||||
compatibilityVersion = "Xcode 9.3";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 0E01EAA025399CB500B0759B;
|
||||
productRefGroup = 0E01EAAB25399CB500B0759B /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
0E01EAA925399CB500B0759B /* PSCBOnline */,
|
||||
0E01EAB225399CB500B0759B /* PSCBOnlineTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
0E01EAA825399CB500B0759B /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0E790FAB253E017E0086AD71 /* LICENSE.txt in Resources */,
|
||||
0E790FA3253DEA930086AD71 /* PSCBOnline.podspec in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
0E01EAB125399CB500B0759B /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
0E01EAA625399CB500B0759B /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0E26F59F2547097300F80DAC /* RSAHelper.swift in Sources */,
|
||||
0EA2C872253CC44A00C5DD14 /* RequestWrapper+Serializable.swift in Sources */,
|
||||
0EA2C86A253B29A900C5DD14 /* PKPaymentToken+Serializable.swift in Sources */,
|
||||
0E0A2C1F25408AA1006BBBA1 /* CardData.swift in Sources */,
|
||||
0EA2C84E2539A5BA00C5DD14 /* Serializable.swift in Sources */,
|
||||
0E0A2C23254093D0006BBBA1 /* Payment+Serializable.swift in Sources */,
|
||||
0E26F5E82548717B00F80DAC /* PSCBAPI.swift in Sources */,
|
||||
0E26F5862542FB5800F80DAC /* Response.swift in Sources */,
|
||||
0E26F58F2545AE5800F80DAC /* JSONDecoders.swift in Sources */,
|
||||
0E01EAD325399DF600B0759B /* CustomerData.swift in Sources */,
|
||||
0E01EACD25399DB000B0759B /* Payment.swift in Sources */,
|
||||
0EA2C8582539F4D500C5DD14 /* PSCBOnlineClient.swift in Sources */,
|
||||
0EA2C8622539FAC200C5DD14 /* PaymentHandler.swift in Sources */,
|
||||
0E01EADE25399E8800B0759B /* RequestWrapper.swift in Sources */,
|
||||
0E26F62E2549591E00F80DAC /* DigestHelper.swift in Sources */,
|
||||
0E01EAD825399E3D00B0759B /* String.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
0E01EAAF25399CB500B0759B /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0EC9DB072540A1C8005392A0 /* OOSAPIClientTests.swift in Sources */,
|
||||
0EC9DB192541D9F9005392A0 /* PKPaymentTokenTests.swift in Sources */,
|
||||
0EC9DB0C2541B699005392A0 /* PassKitMocks.swift in Sources */,
|
||||
0E26F58A2542FE2000F80DAC /* ResponseTests.swift in Sources */,
|
||||
0EC9DB132541BF45005392A0 /* PKPaymentToken+SerializableTests.swift in Sources */,
|
||||
0E26F5A3254714B600F80DAC /* CardDataTests.swift in Sources */,
|
||||
0E26F63325495A5B00F80DAC /* DigestHelperTests.swift in Sources */,
|
||||
0E01EAE425399EE800B0759B /* PaymentTests.swift in Sources */,
|
||||
0E01EAB925399CB500B0759B /* PSCBOnlineTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
0E01EAB625399CB500B0759B /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 0E01EAA925399CB500B0759B /* PSCBOnline */;
|
||||
targetProxy = 0E01EAB525399CB500B0759B /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
0E01EABC25399CB500B0759B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
0E01EABD25399CB500B0759B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
0E01EABF25399CB500B0759B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = 46N426YCGP;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INFOPLIST_FILE = PSCBOnline/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "ru.pscb.oos-ios-sdk";
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
0E01EAC025399CB500B0759B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = 46N426YCGP;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INFOPLIST_FILE = PSCBOnline/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "ru.pscb.oos-ios-sdk";
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
0E01EAC225399CB500B0759B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 46N426YCGP;
|
||||
INFOPLIST_FILE = PSCBOnlineTests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = ru.pscb.PSCBOnlineTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
0E01EAC325399CB500B0759B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 46N426YCGP;
|
||||
INFOPLIST_FILE = PSCBOnlineTests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = ru.pscb.PSCBOnlineTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
0E01EAA425399CB500B0759B /* Build configuration list for PBXProject "PSCBOnline" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
0E01EABC25399CB500B0759B /* Debug */,
|
||||
0E01EABD25399CB500B0759B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
0E01EABE25399CB500B0759B /* Build configuration list for PBXNativeTarget "PSCBOnline" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
0E01EABF25399CB500B0759B /* Debug */,
|
||||
0E01EAC025399CB500B0759B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
0E01EAC125399CB500B0759B /* Build configuration list for PBXNativeTarget "PSCBOnlineTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
0E01EAC225399CB500B0759B /* Debug */,
|
||||
0E01EAC325399CB500B0759B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 0E01EAA125399CB500B0759B /* Project object */;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
BIN
PSCBOnline.xcodeproj/project.xcworkspace/xcuserdata/oa.xcuserdatad/UserInterfaceState.xcuserstate
generated
Normal file
BIN
PSCBOnline.xcodeproj/project.xcworkspace/xcuserdata/oa.xcuserdatad/UserInterfaceState.xcuserstate
generated
Normal file
Binary file not shown.
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>PSCBOnline.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>0E01EAA925399CB500B0759B</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>0E01EAB225399CB500B0759B</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,18 @@
|
|||
//
|
||||
// PSCBOnline.h
|
||||
// PSCBOnline
|
||||
//
|
||||
// Created by Antonov Ilia on 16.10.2020.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
//! Project version number for PSCBOnline.
|
||||
FOUNDATION_EXPORT double PSCBOnlineVersionNumber;
|
||||
|
||||
//! Project version string for PSCBOnline.
|
||||
FOUNDATION_EXPORT const unsigned char PSCBOnlineVersionString[];
|
||||
|
||||
// In this header, you should import all the public headers of your framework using statements like #import <PSCBOnline/PublicHeader.h>
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// String.swift
|
||||
//
|
||||
//
|
||||
// Created by AntonovIA on 12.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension String {
|
||||
|
||||
private static let alphanumeric = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
|
||||
static func random(length: Int, allowedChars: String? = nil) -> String {
|
||||
let seq: String = ((allowedChars == nil) ? alphanumeric : allowedChars!) as String
|
||||
var rnd: String = ""
|
||||
|
||||
for _ in 0..<length {
|
||||
let randInt = arc4random_uniform(UInt32(seq.count))
|
||||
rnd += "\(seq[seq.index(seq.startIndex, offsetBy: Int(randInt))])"
|
||||
}
|
||||
|
||||
return rnd
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// DigestHelper.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by Antonov Ilia on 28.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CommonCrypto
|
||||
|
||||
public struct DigestHelper {
|
||||
|
||||
public static func sha256String(_ string: String) -> String {
|
||||
let data = string.data(using: .utf8)!
|
||||
var hash = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
|
||||
var sign = ""
|
||||
|
||||
data.withUnsafeBytes {
|
||||
_ = CC_SHA256($0.baseAddress, CC_LONG(data.count), &hash)
|
||||
}
|
||||
|
||||
for byte in hash {
|
||||
sign += String(format: "%02x", UInt8(byte))
|
||||
}
|
||||
|
||||
return sign.lowercased()
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
//
|
||||
// JSONDecoders.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by Antonov Ilia on 25.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
final public class JSONDecoders {
|
||||
|
||||
public static func iso8601DateAwareDecoder() -> JSONDecoder {
|
||||
return ISO8601DateAwareJSONDecoder()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - ISO8601 date aware JSON Decoder
|
||||
class ISO8601DateAwareJSONDecoder: JSONDecoder {
|
||||
|
||||
static internal let dateTimeFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
|
||||
|
||||
let dateFormatter: DateFormatter = DateFormatter()
|
||||
let calendar = Calendar.current
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
dateFormatter.dateFormat = Self.dateTimeFormat
|
||||
dateDecodingStrategy = .formatted(dateFormatter)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
//
|
||||
// RSAHelper.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by Antonov Ilia on 26.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum RSAKeyError: Error {
|
||||
|
||||
/// Thrown when provided public key is invalid
|
||||
case invalidKey
|
||||
|
||||
/// Thrown when encryption of message failed
|
||||
case encryption(OSStatus)
|
||||
|
||||
/// Thrown when unable to initialize `SecKey` with given key string
|
||||
case unmanaged(Unmanaged<CFError>)
|
||||
}
|
||||
|
||||
public final class RSAHelper {
|
||||
|
||||
internal static let key = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAPQsWyHaynwoc2tuMbengf1SFase9tPnwtPh4o1tR+94xsWztADdhhUaUBk/68ipaoZE8uSnM9UgdEPmOotFXyUCAwEAAQ=="
|
||||
|
||||
internal static var secKey: SecKey? = nil
|
||||
|
||||
static func initPSCBOnlinePublicKey() throws {
|
||||
// Treat as assert
|
||||
guard let keyData = Data(base64Encoded: key) else {
|
||||
print("Invalid key string: \(key)")
|
||||
throw RSAKeyError.invalidKey
|
||||
}
|
||||
|
||||
var attributes: CFDictionary {
|
||||
return [
|
||||
kSecAttrKeyType: kSecAttrKeyTypeRSA,
|
||||
kSecAttrKeyClass: kSecAttrKeyClassPublic,
|
||||
kSecAttrKeySizeInBits: 2048,
|
||||
kSecReturnPersistentRef: true
|
||||
] as CFDictionary
|
||||
}
|
||||
|
||||
var error: Unmanaged<CFError>? = nil
|
||||
guard let secKey = SecKeyCreateWithData(keyData as CFData, attributes, &error) else {
|
||||
print("Error creating a security key with \(String(describing: keyData))")
|
||||
print(error.debugDescription)
|
||||
throw RSAKeyError.unmanaged(error!)
|
||||
}
|
||||
|
||||
Self.secKey = secKey
|
||||
}
|
||||
|
||||
/// Encrypts given message with OOS public key.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - message: A message to encrypt.
|
||||
///
|
||||
/// - Returns: A base64 encoded string
|
||||
///
|
||||
/// - Throws: `RSAKeyError` type error
|
||||
public static func encryptEncodeBase64(message: String) throws -> String {
|
||||
// Initialize OOS public key
|
||||
if Self.secKey == nil {
|
||||
try Self.initPSCBOnlinePublicKey()
|
||||
}
|
||||
|
||||
// Initialize buffers
|
||||
let sKey = Self.secKey!
|
||||
let buff = [UInt8](message.utf8)
|
||||
|
||||
// Mutable encryption refs
|
||||
var size = SecKeyGetBlockSize(sKey)
|
||||
var kBuf = [UInt8](repeating: 0, count: size)
|
||||
|
||||
let status = SecKeyEncrypt(sKey, SecPadding.PKCS1, buff, buff.count, &kBuf, &size)
|
||||
|
||||
// Sanity check
|
||||
guard status == errSecSuccess else {
|
||||
throw RSAKeyError.encryption(status)
|
||||
}
|
||||
|
||||
return Data(bytes: kBuf, count: size).base64EncodedString()
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
//
|
||||
// CardData.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by Antonov Ilia on 21.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import PassKit
|
||||
|
||||
public enum CardDataError: Error {
|
||||
case invalidExiryDate(String)
|
||||
case invalidCvCode
|
||||
case invalidPan
|
||||
}
|
||||
|
||||
/// Billing info.
|
||||
/// Detailed card information
|
||||
public struct CardData {
|
||||
let pan: String
|
||||
let expiryYear: Int
|
||||
let expiryMonth: Int
|
||||
let cardholder: String?
|
||||
let cvCode: String
|
||||
|
||||
/// Constructs card data from all necessary for billing fields
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - pan: Card number
|
||||
/// - expiryYear: A full year number (e.g: `2020`). For production cannot be in the past
|
||||
/// - expiryMonth: A month number from 1 to 12.
|
||||
/// - cvCode: CVC/CVV number
|
||||
/// - cardholder: (Optional) Cardholder name in latin.
|
||||
///
|
||||
/// - Returns: optional instance of a new card. If validation fails returns nil
|
||||
public init?(pan: String, expiryYear: Int, expiryMonth: Int, cvCode: String, cardholder: String? = nil) {
|
||||
guard expiryMonth >= 1 && expiryMonth <= 12 else {
|
||||
print("Month can be between 1 and 12")
|
||||
return nil
|
||||
}
|
||||
|
||||
#if !DEBUG
|
||||
// todo check year + month in the past
|
||||
let currentYear = Calendar.current.component(.year, from: Date())
|
||||
guard expiryYear >= currentYear else {
|
||||
print("Year must be current or in the future")
|
||||
return nil
|
||||
}
|
||||
#endif
|
||||
|
||||
self.pan = pan
|
||||
self.expiryMonth = expiryMonth
|
||||
self.expiryYear = expiryYear
|
||||
self.cvCode = cvCode
|
||||
self.cardholder = cardholder
|
||||
}
|
||||
|
||||
/// - Returns: A last 2 digits of the expiry year
|
||||
public func getExpYearString() -> String {
|
||||
return String(String(expiryYear).dropFirst(2))
|
||||
}
|
||||
|
||||
/// - Returns: A zero padded expiry month string
|
||||
public func getExpMonthString() -> String {
|
||||
return expiryMonth < 10 ? "0\(self.expiryMonth)" : String(self.expiryMonth)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension CardData {
|
||||
|
||||
internal static let pubKey: Data = {
|
||||
let key = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAPQsWyHaynwoc2tuMbengf1SFase9tPnwtPh4o1tR+94xsWztADdhhUaUBk/68ipaoZE8uSnM9UgdEPmOotFXyUCAwEAAQ=="
|
||||
|
||||
return Data(base64Encoded: key)!
|
||||
}()
|
||||
|
||||
|
||||
/// Produces a cryptogram string from given `CardData`
|
||||
/// See: https://docs.pscb.ru/oos/shpa.html#shlyuz-prozrachnoj-avtorizacii-sozdanie-platezha-otvet
|
||||
///
|
||||
/// - Returns: a Base64 encoded cryptogram string
|
||||
public func toCryptgramString() throws -> String {
|
||||
let month = self.getExpMonthString()
|
||||
let year = self.getExpYearString()
|
||||
let joinedString = "\(self.pan)|\(month)|\(year)|\(cvCode)\(self.cardholder ?? "")"
|
||||
let base64Encode = try RSAHelper.encryptEncodeBase64(message: joinedString)
|
||||
|
||||
return base64Encode
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// CustomerData.swift
|
||||
//
|
||||
//
|
||||
// Created by Antonov Ilia on 12.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// A costumer data to present in PaymentData
|
||||
public struct CustomerData: Codable {
|
||||
|
||||
/// Unique costumer ID
|
||||
let account: String
|
||||
|
||||
let comment: String?
|
||||
|
||||
let email: String?
|
||||
|
||||
let phone: String?
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case account = "customerAccount"
|
||||
case comment = "customerComment"
|
||||
case email = "customerEmail"
|
||||
case phone = "customerPhone"
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
//
|
||||
// Payment.swift
|
||||
//
|
||||
//
|
||||
// Created by AntonovIA on 12.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// MARK: - Payment methods
|
||||
|
||||
internal enum PaymentMethods: String {
|
||||
case shpa = "ac-shpa"
|
||||
}
|
||||
|
||||
// MARK: - Request Message
|
||||
|
||||
public struct Payment: Encodable {
|
||||
|
||||
// Required:
|
||||
|
||||
/// Payment amount in rub
|
||||
/// min: 1.00
|
||||
public let amount: Decimal
|
||||
|
||||
/// Your market order ID
|
||||
/// maxlength: 20
|
||||
public let orderId: String
|
||||
|
||||
// Payment method
|
||||
internal let paymentMethod: PaymentMethods = .shpa
|
||||
|
||||
// Optional:
|
||||
|
||||
/// Human readable `orderId`
|
||||
/// Defaults to `orderId`
|
||||
var showOrderId: String?
|
||||
|
||||
/// Detailed text describing this order payment.
|
||||
var details: String?
|
||||
|
||||
/// Data about paying customer
|
||||
var customer: CustomerData?
|
||||
|
||||
// <Not in use>
|
||||
var recurrentable: Bool = false
|
||||
|
||||
public init(amount: Decimal, orderId: String,
|
||||
showOrderId: String? = nil, details: String? = nil,
|
||||
customer: CustomerData? = nil, recurrentable: Bool = false) {
|
||||
self.amount = amount
|
||||
self.orderId = orderId
|
||||
self.showOrderId = (showOrderId == nil) ? orderId : showOrderId
|
||||
self.details = details
|
||||
self.customer = customer
|
||||
self.recurrentable = recurrentable
|
||||
}
|
||||
|
||||
// MARK: - Encoder
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case amount, orderId, showOrderId, details, recurrentable, customer
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(amount, forKey: .amount)
|
||||
try container.encode(orderId, forKey: .orderId)
|
||||
try container.encode(showOrderId, forKey: .showOrderId)
|
||||
try container.encode(details, forKey: .details)
|
||||
try container.encode(recurrentable, forKey: .recurrentable)
|
||||
|
||||
// Customer
|
||||
try customer?.encode(to: encoder)
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
|
||||
public static let example = Payment(
|
||||
amount: 150.00, orderId: String.random(length: 6),
|
||||
details: "Wonderful warm socks",
|
||||
customer: CustomerData(
|
||||
account: "ID-12345", comment: "By tomorrow please",
|
||||
email: "foo@bar.com", phone: "+7 900 000 00 00"
|
||||
)
|
||||
)
|
||||
|
||||
#endif
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
//
|
||||
// RequestWrapper.swift
|
||||
//
|
||||
//
|
||||
// Created by Antonov Ilia on 12.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// MARK: - Top level request
|
||||
|
||||
/// Top level request wrapper for OOS requests
|
||||
public struct RequestWrapper: Encodable {
|
||||
|
||||
/// Merchant ID
|
||||
public let marketPlaceId: String
|
||||
|
||||
/// Payment info
|
||||
public let payment: Payment
|
||||
|
||||
/// Encoded card data
|
||||
public let cardData: String
|
||||
|
||||
/// Creates instance of RequestWrapper
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - marketPlaceId: Your OOS market place ID
|
||||
/// - payment: Payment details object
|
||||
/// - cardData: Encoded card data
|
||||
///
|
||||
/// - Returns: Prepared request ready to fire
|
||||
public init(marketPlaceId: String, payment: Payment, cardData: String) {
|
||||
self.marketPlaceId = marketPlaceId
|
||||
self.payment = payment
|
||||
self.cardData = cardData
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case marketPlaceId = "marketPlace"
|
||||
case payment
|
||||
case cardData
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
//
|
||||
// Response.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by Antonov Ilia on 23.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// MARK: - PSCB OOS Response status
|
||||
public enum ResponseStatus: String, Decodable {
|
||||
case success = "STATUS_SUCCESS"
|
||||
case failure = "STATUS_FAILURE"
|
||||
}
|
||||
|
||||
// MARK: - Acquiring data
|
||||
public struct AcquiringResponseData: Decodable {
|
||||
public let paReq: String?
|
||||
public let order: String?
|
||||
public let termUrl: String?
|
||||
public let url: String?
|
||||
public let md: String?
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case order, termUrl = "TermUrl", url = "URL", md = "MD", paReq = "PaReq"
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - OOS Error
|
||||
|
||||
/// An error structure for OOS errors returned in flat JSON
|
||||
/// `errorCode` and `errorDescription`
|
||||
public struct ResponseError: Decodable {
|
||||
|
||||
public let code: String
|
||||
public let description: String?
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case code = "errorCode"
|
||||
case description = "errorDescription"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - OOS Response
|
||||
|
||||
/// JSON Response from OOS API
|
||||
public struct Response: Decodable {
|
||||
|
||||
public let status: ResponseStatus
|
||||
public let requestId: String
|
||||
public let error: ResponseError?
|
||||
public let payment: ResponsePayment?
|
||||
public let acquiringData: AcquiringResponseData?
|
||||
public let description: String?
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case status, requestId, payment, acquiringData, description
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
self.status = try container.decode(ResponseStatus.self, forKey: .status)
|
||||
self.requestId = try container.decode(String.self, forKey: .requestId)
|
||||
self.description = try? container.decode(String.self, forKey: .description)
|
||||
|
||||
// Decode flat and nested data into nested structs
|
||||
self.payment = try? container.decode(ResponsePayment.self, forKey: .payment)
|
||||
self.acquiringData = try? AcquiringResponseData(from: decoder)
|
||||
self.error = try? ResponseError(from: decoder)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Payment status
|
||||
/// Payment stats
|
||||
/// see: https://docs.pscb.ru/oos/index.html#obshaya-informaciya-spravochniki-statusy-platezhej
|
||||
public enum PaymentState: String, Decodable {
|
||||
case sent = "sent"
|
||||
case new = "new"
|
||||
case end = "end"
|
||||
case refunded = "ref"
|
||||
case hold = "hold"
|
||||
case expired = "exp"
|
||||
case canceled = "canceled"
|
||||
case error = "error"
|
||||
case rejected = "rej"
|
||||
case undefined = "undef"
|
||||
}
|
||||
|
||||
// MARK: - Payment response struct
|
||||
public struct ResponsePayment: Decodable {
|
||||
public let orderId: String
|
||||
public let showOrderId: String
|
||||
public let paymentId: String
|
||||
public let amount: Decimal
|
||||
public let state: PaymentState
|
||||
public let marketPlace: UInt16
|
||||
public let stateDate: Date
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
//
|
||||
// OOSAPI.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by Antonov Ilia on 27.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import PassKit
|
||||
|
||||
/// Utility fabric methods required for PSCB API.
|
||||
public class PSCBAPI {
|
||||
|
||||
public static let supportedNetworks: [PKPaymentNetwork] = [.visa, .masterCard]
|
||||
|
||||
/// - Returns: a tuple describing if application `canMakePayments` and `canSetupCards` using supported networks.
|
||||
public class func canMakePayments() -> (canMakePayments: Bool, canSetupCards: Bool) {
|
||||
return (
|
||||
PKPaymentAuthorizationController.canMakePayments(),
|
||||
PKPaymentAuthorizationController.canMakePayments(usingNetworks: supportedNetworks)
|
||||
)
|
||||
}
|
||||
|
||||
/// Creates a default instance of `PKPaymentRequest` with pre-default parameters.
|
||||
///
|
||||
/// - Returns: `PKPaymentRequest`
|
||||
public class func makePaymentRequest(items: [PKPaymentSummaryItem]) -> PKPaymentRequest {
|
||||
return makePaymentRequest(merchantId: "merchant.pscb.pay", items: items)
|
||||
}
|
||||
|
||||
/// Creates a default instance of `PKPaymentRequest` with pre-default parameters.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - merchantId: Your Apple Pay merchant ID
|
||||
/// - items: Summary items
|
||||
///
|
||||
/// - Returns: `PKPaymentRequest`
|
||||
public class func makePaymentRequest(merchantId: String, items: [PKPaymentSummaryItem]) -> PKPaymentRequest {
|
||||
let request = PKPaymentRequest()
|
||||
request.merchantIdentifier = merchantId
|
||||
request.supportedNetworks = Self.supportedNetworks
|
||||
|
||||
if #available(iOS 11.0, *) {
|
||||
//request.supportedCountries = ["RU", "UA", "BY", "US"]
|
||||
}
|
||||
|
||||
request.merchantCapabilities = .capability3DS
|
||||
request.countryCode = "RU"
|
||||
request.currencyCode = "RUB"
|
||||
request.paymentSummaryItems = items
|
||||
|
||||
return request
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,306 @@
|
|||
//
|
||||
// OOSAPIClient.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by Antonov Ilia on 12.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import PassKit
|
||||
|
||||
// MARK: - Environments
|
||||
|
||||
public enum BackendEnvironment: String {
|
||||
|
||||
case production = "oos.pscb.ru"
|
||||
case sandbox = "oosdemo.pscb.ru"
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Request status
|
||||
|
||||
/// Backend request status
|
||||
/// Consists of two possible states: `.success` and `.failure`.
|
||||
///
|
||||
/// This one represents if request to the backend server was successful
|
||||
public enum RequestStatus {
|
||||
case success, failure
|
||||
}
|
||||
|
||||
// MARK: - Response wrapper
|
||||
|
||||
/// Backend response
|
||||
public struct BackendResponse {
|
||||
|
||||
/// Represents request status
|
||||
public let status: RequestStatus
|
||||
|
||||
/// Hold error information if request is a `.failure`
|
||||
public let error: Error?
|
||||
|
||||
/// Holds response information if request is a `.success`
|
||||
public let response: Response?
|
||||
}
|
||||
|
||||
// MARK: - Alias for completion handler
|
||||
|
||||
/// Callback for `OOSAPIClient.send` method
|
||||
public typealias APICompletionHandler = (BackendResponse) -> Void
|
||||
|
||||
/// Callback for another `OOSAPIClient.send` method which fires after certain guards ensure success or failure
|
||||
/// to simplify API usage
|
||||
public typealias PostResponseHandler = (Error?, Response?) -> Void
|
||||
|
||||
// MARK: - API Integration errors
|
||||
|
||||
/// Possible erros when dealing with OOS backend
|
||||
public enum OOSErrors: Error {
|
||||
case noData
|
||||
case parse(Error)
|
||||
case cause(Error)
|
||||
|
||||
/// Consists of error code and error description
|
||||
case backend(String, String)
|
||||
}
|
||||
|
||||
// MARK: - API Client
|
||||
|
||||
/// Implementation of OOS Merchant API HTTP protocol.
|
||||
final public class PSCBOnlineClient {
|
||||
|
||||
private lazy var urlSession: URLSession = {
|
||||
URLSession(configuration: .default, delegate: nil, delegateQueue: .main)
|
||||
}()
|
||||
|
||||
private lazy var url: URL = {
|
||||
var components = URLComponents()
|
||||
components.scheme = "https"
|
||||
components.host = self.environment.rawValue
|
||||
components.path = "/merchantApi/payShpa"
|
||||
|
||||
return components.url!
|
||||
}()
|
||||
|
||||
private let decoder = JSONDecoders.iso8601DateAwareDecoder()
|
||||
|
||||
// init:
|
||||
|
||||
let environment: BackendEnvironment
|
||||
let marketPlaceId: String
|
||||
let signingKey: String
|
||||
|
||||
/// Initializes `OOSAPIClient`
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - environment: Backend environment. Which one to use. For testing environment use `.sandbox`
|
||||
/// - marketPlaceId: Your OOS market-place ID
|
||||
/// - siginingKey: Your OOS signing key
|
||||
public init(environment: BackendEnvironment, marketPlaceId: String, signingKey: String) {
|
||||
self.environment = environment
|
||||
self.marketPlaceId = marketPlaceId
|
||||
self.signingKey = signingKey
|
||||
}
|
||||
|
||||
// impl:
|
||||
|
||||
/// Creates instance of `RequestWrapper` for a backend to process from given PKPayment instance and other details
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - payment: authorized PKPayment instance
|
||||
/// - amount: total order amount
|
||||
/// - orderId: Unique merchant order ID
|
||||
///
|
||||
/// - Returns: RequestWrapper instance for backend
|
||||
public func makeRequestWithPayment(payment: PKPayment, amount: Decimal, orderId: String) throws -> RequestWrapper {
|
||||
return try makeRequestWithPayment(pkPayment: payment, payment: Payment(amount: amount, orderId: orderId))
|
||||
}
|
||||
|
||||
/// Creates instance of `RequestWrapper` for a backend to process from given `PKPayment` instance and backend `Payment` instance
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - pkPayment: authorized `PKPayment` instance
|
||||
/// - payment: backend `Payment` details
|
||||
///
|
||||
/// - Returns: RequestWrapper instance for backend
|
||||
public func makeRequestWithPayment(pkPayment: PKPayment, payment: Payment) throws -> RequestWrapper {
|
||||
// Get card data cryptogram from payment token
|
||||
let cardDataCrypto = try pkPayment.token.toCryptogramString()
|
||||
|
||||
// Backend request wrapper
|
||||
let requestWrapper = RequestWrapper(
|
||||
marketPlaceId: self.marketPlaceId,
|
||||
payment: payment,
|
||||
cardData: cardDataCrypto
|
||||
)
|
||||
|
||||
// Fail early
|
||||
try requestWrapper.assumeSerializes()
|
||||
|
||||
return requestWrapper
|
||||
}
|
||||
|
||||
/// Creates instance of `RequestWrapper` for a backend to process from raw card data instead of ApplePay token
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// let card = CardData(
|
||||
/// pan: "409444400001234",
|
||||
/// expiryYear: 2025,
|
||||
/// expiryMonth: 12,
|
||||
/// cvCode: "000",
|
||||
/// cardholder: "JOHN DOE"
|
||||
/// )
|
||||
///
|
||||
/// let payment = Payment(amount: Decimal(1500), orderId: "XC-12345")
|
||||
/// let request = try apiClient.createRequestWithCardData(card: card, payment: payment)
|
||||
///
|
||||
/// // Send to backend:
|
||||
/// apiClient.send(request) { (response) in /code/ }
|
||||
/// ```
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - cardData: an instance of card data.
|
||||
public func makeRequestWithCardData(card: CardData, payment: Payment) throws -> RequestWrapper {
|
||||
let cryptogram = try card.toCryptgramString()
|
||||
let request = RequestWrapper(
|
||||
marketPlaceId: self.marketPlaceId,
|
||||
payment: payment,
|
||||
cardData: cryptogram
|
||||
)
|
||||
|
||||
// Fail-early compile
|
||||
try request.assumeSerializes()
|
||||
|
||||
return request
|
||||
}
|
||||
|
||||
/// Signs and sends compiled `RequestWrapper` to the backend server
|
||||
/// Fires `APICompletionHandler` once requests succeeds or fails
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - request: `RequestWrapper` created from `createRequestWithPayment(...)`
|
||||
/// - completionHander: `APICompletionHandler` a callback for when requests succeeds or fails
|
||||
///
|
||||
public func send(_ request: RequestWrapper, completionHandler: @escaping APICompletionHandler) {
|
||||
// Calculate signature and get HTTP body at the same time
|
||||
let httpBody = try! request.serializeToString()
|
||||
let signature = calculateSignature(httpBody)
|
||||
|
||||
// Request params
|
||||
let url = self.url
|
||||
var req = URLRequest(url: url)
|
||||
|
||||
// Set request parameters
|
||||
req.httpMethod = "POST"
|
||||
req.httpBody = httpBody.data(using: .utf8)
|
||||
req.setValue(signature, forHTTPHeaderField: "Signature")
|
||||
|
||||
print(">> Request JSON: \(String(describing: String(data: req.httpBody!, encoding: .utf8)))")
|
||||
|
||||
let task = urlSession.dataTask(with: req) { (data, res, err) in
|
||||
guard err == nil else {
|
||||
let error = self.err_requestError(req, error: err)
|
||||
completionHandler(error)
|
||||
return
|
||||
}
|
||||
|
||||
guard let data = data else {
|
||||
let error = self.failure(req, error: OOSErrors.noData)
|
||||
completionHandler(error)
|
||||
return
|
||||
}
|
||||
|
||||
print("<< Response data: \(String(data: data, encoding: .utf8) ?? "N/A")")
|
||||
|
||||
do {
|
||||
let response = try self.decoder.decode(Response.self, from: data)
|
||||
|
||||
// Finaly success
|
||||
let success = BackendResponse(status: .success, error: nil, response: response)
|
||||
|
||||
completionHandler(success)
|
||||
} catch let error {
|
||||
print("Failed to do task on request \(req)")
|
||||
print(error.localizedDescription)
|
||||
|
||||
// Reading and parsing errors
|
||||
let failure = self.failure(req, error: .parse(error))
|
||||
completionHandler(failure)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Fire task
|
||||
task.resume()
|
||||
}
|
||||
|
||||
/// Signs and sends compiled `RequestWrapper` to the backend server
|
||||
/// Fires `PostResponseHandler` once requests succeeds or fails.
|
||||
/// `PostResponseHandler` accepts two arguments: `Error?` and `Response?`.
|
||||
///
|
||||
/// If requests succeeds and payment in desired state `Error?` will always be `nil`.
|
||||
/// `Response?` presents on some errors and on all successes.
|
||||
///
|
||||
/// This is an utility method to reduce boilerplate for necessary checks.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - request: `RequestWrapper` created from `createRequestWithPayment(...)`
|
||||
/// - completionHander: `APICompletionHandler` a callback for when requests succeeds or fails
|
||||
///
|
||||
public func send(_ request: RequestWrapper, responseHandler: @escaping PostResponseHandler) {
|
||||
// Construct a closure wrapper with predefined guards and checks
|
||||
let wrapper: APICompletionHandler = { (backendResponse) in
|
||||
// HTTP request succeeded?
|
||||
guard backendResponse.status == .success else {
|
||||
print("Failed to execute request due to error: \(String(describing: backendResponse.error))")
|
||||
|
||||
responseHandler(OOSErrors.cause(backendResponse.error!), nil)
|
||||
return
|
||||
}
|
||||
|
||||
// Backend returned valid response?
|
||||
guard let response = backendResponse.response else {
|
||||
print("Backend returned empty body")
|
||||
|
||||
responseHandler(OOSErrors.noData, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// Backend payment succeeded?
|
||||
guard response.status == .success else {
|
||||
print("Unable to process payment")
|
||||
|
||||
let responseError = response.error
|
||||
let backendError = OOSErrors.backend(responseError?.code ?? "FAILED", responseError?.description ?? "")
|
||||
|
||||
// At this point we can pass response too
|
||||
responseHandler(backendError, response)
|
||||
return
|
||||
}
|
||||
|
||||
// Finally succeeds
|
||||
responseHandler(nil, response)
|
||||
}
|
||||
|
||||
// Send using more lower-level method above
|
||||
send(request, completionHandler: wrapper)
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func err_requestError(_ req: URLRequest, error: Error?) -> BackendResponse {
|
||||
print("Failed to do task on request \(req) with error: \(String(describing: error))")
|
||||
return BackendResponse(status: .failure, error: OOSErrors.cause(error!), response: nil)
|
||||
}
|
||||
|
||||
private func failure(_ req: URLRequest, error: OOSErrors) -> BackendResponse {
|
||||
print("Request \(req) failed with error: \(String(describing: error))")
|
||||
return BackendResponse(status: .failure, error: error, response: nil)
|
||||
}
|
||||
|
||||
private func calculateSignature(_ jsonString: String) -> String {
|
||||
let composite = (jsonString + self.signingKey)
|
||||
return DigestHelper.sha256String(composite)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
//
|
||||
// PaymentHandler.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by Antonov Ilia on 16.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import PassKit
|
||||
|
||||
public typealias PaymentCompletionHandler = (Bool) -> Void
|
||||
|
||||
public class ApplePayHandler: NSObject {
|
||||
|
||||
static let supportedNetworks: [PKPaymentNetwork] = [.visa, .masterCard]
|
||||
|
||||
// MARK: - Fields
|
||||
|
||||
public let merchantId: String
|
||||
public let merchantKey: String
|
||||
public let summaryItems: [PKPaymentSummaryItem]
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
var paymentController: PKPaymentAuthorizationController?
|
||||
var paymentStatus: PKPaymentAuthorizationStatus = .failure
|
||||
var completionHandler: PaymentCompletionHandler?
|
||||
var payment: Payment?
|
||||
|
||||
public init?(merchantId: String, merchantKey: String, summaryItems: [PKPaymentSummaryItem]) {
|
||||
guard PKPaymentAuthorizationController.canMakePayments(usingNetworks: Self.supportedNetworks) else {
|
||||
print("Could not instantiate ApplePayHandler. Cannot make payments with provided networks")
|
||||
return nil
|
||||
}
|
||||
|
||||
self.merchantId = merchantId
|
||||
self.merchantKey = merchantKey
|
||||
self.summaryItems = summaryItems
|
||||
}
|
||||
|
||||
public func handle(payment: Payment, completion: @escaping PaymentCompletionHandler) {
|
||||
self.completionHandler = completion
|
||||
self.payment = payment
|
||||
|
||||
NSLog("About to handle payment: \(payment)")
|
||||
|
||||
paymentController = PKPaymentAuthorizationController(paymentRequest: paymentRequest)
|
||||
paymentController?.delegate = self
|
||||
paymentController?.present { (presented) in
|
||||
if !presented {
|
||||
NSLog("Could not present PKPaymentAuthorizationController")
|
||||
self.completionHandler!(false)
|
||||
} else {
|
||||
NSLog("PKPaymentAuthorizationController presented")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Private details
|
||||
|
||||
private var paymentRequest: PKPaymentRequest {
|
||||
let request = PKPaymentRequest()
|
||||
|
||||
request.countryCode = "RU"
|
||||
request.merchantIdentifier = "merchant.pscb.pay"
|
||||
request.currencyCode = "RUB"
|
||||
request.supportedNetworks = Self.supportedNetworks
|
||||
request.merchantCapabilities = .capability3DS
|
||||
request.paymentSummaryItems = summaryItems
|
||||
|
||||
return request
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Extension for PKPaymentAuthorizationControllerDelegate
|
||||
|
||||
extension ApplePayHandler: PKPaymentAuthorizationControllerDelegate {
|
||||
|
||||
public func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController,
|
||||
didAuthorizePayment payment: PKPayment,
|
||||
completion: @escaping (PKPaymentAuthorizationStatus) -> Void) {
|
||||
|
||||
// print("Payment string")
|
||||
// let paymentString = try! payment.serializeToString()
|
||||
// print(paymentString)
|
||||
//
|
||||
// //
|
||||
//
|
||||
// self.paymentStatus = .success
|
||||
completion(PKPaymentAuthorizationStatus.success)
|
||||
}
|
||||
|
||||
@available(iOS 11.0, *)
|
||||
public func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController, didAuthorizePayment payment: PKPayment, handler completion: @escaping (PKPaymentAuthorizationResult) -> Void) {
|
||||
//
|
||||
// NSLog("About to send request to backend")
|
||||
// let paymentString = try! payment.serializeToString()
|
||||
//
|
||||
// NSLog("Payment JSON: \(paymentString)")
|
||||
//
|
||||
let result = PKPaymentAuthorizationResult(status: .success, errors: nil)
|
||||
completion(result)
|
||||
self.completionHandler?(true)
|
||||
}
|
||||
|
||||
public func paymentAuthorizationControllerDidFinish(_ controller: PKPaymentAuthorizationController) {
|
||||
controller.dismiss(completion: nil)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
//
|
||||
// PKPaymentToken+Serializable.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by OA on 17.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import PassKit
|
||||
|
||||
// MARK: - Comfront to serializable
|
||||
extension PKPaymentToken: Serializable {
|
||||
|
||||
// Serializes token to a JSONLike dictionary
|
||||
public func serializeToJSON() -> JSONDict {
|
||||
let paymentJson: JSONDict? = try? JSONSerialization.jsonObject(
|
||||
with: self.paymentData, options: .mutableContainers
|
||||
) as? JSONDict
|
||||
|
||||
var paymentType: String = "debit"
|
||||
var methodAndNetwork: JSONDict = [
|
||||
"network": "",
|
||||
"type": paymentType,
|
||||
"displayName": ""
|
||||
]
|
||||
|
||||
if #available(iOS 9.0, *) {
|
||||
methodAndNetwork = [
|
||||
"network": self.paymentMethod.network?.rawValue ?? "",
|
||||
"type": paymentType,
|
||||
"displayName": self.paymentMethod.displayName ?? ""
|
||||
]
|
||||
|
||||
switch self.paymentMethod.type {
|
||||
case .debit:
|
||||
paymentType = "debit"
|
||||
case .credit:
|
||||
paymentType = "credit"
|
||||
case .store:
|
||||
paymentType = "store"
|
||||
case .prepaid:
|
||||
paymentType = "prepaid"
|
||||
default:
|
||||
paymentType = "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
"paymentData": paymentJson,
|
||||
"transactionIdentifier": self.transactionIdentifier,
|
||||
"paymentMethod": methodAndNetwork
|
||||
] as JSONDict
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - To string cryptogram
|
||||
extension PKPaymentToken {
|
||||
|
||||
private func paymentJSONData() -> JSONDict? {
|
||||
let json = self.serializeToJSON()
|
||||
let data = json["paymentData"] as! JSONDict?
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
/// Creates a Base64 encoded cryptogram string accepted by PSCB OOS protocol
|
||||
/// May throw JSON serialization errors if token could not be converted to JSON string before writing a cryptogram.
|
||||
///
|
||||
/// - Returns: Base64 encoded string
|
||||
public func toCryptogramString() throws -> String {
|
||||
let json = self.paymentJSONData()
|
||||
let data = try JSONSerialization.data(withJSONObject: json!, options: [])
|
||||
// let string = String(data: data, encoding: .utf8)!
|
||||
|
||||
return data.base64EncodedString(options: Data.Base64EncodingOptions(rawValue: 0))
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// Payment+Serializable.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by Antonov Ilia on 21.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Payment: Serializable {
|
||||
|
||||
public func serializeToJSON() -> JSONDict {
|
||||
var json = JSONDict()
|
||||
json["orderId"] = self.orderId
|
||||
json["amount"] = self.amount
|
||||
json["showOrderId"] = self.showOrderId
|
||||
json["details"] = self.details
|
||||
json["recurrentable"] = self.recurrentable
|
||||
json["customerAccount"] = self.customer?.account
|
||||
json["customerComment"] = self.customer?.comment
|
||||
json["customerEmail"] = self.customer?.email
|
||||
json["customerPhone"] = self.customer?.phone
|
||||
|
||||
return json
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// RequestWrapper+Serializable.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by Antonov Ilia on 18.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension RequestWrapper: Serializable {
|
||||
|
||||
public func serializeToJSON() -> JSONDict {
|
||||
var json = JSONDict()
|
||||
json["marketPlace"] = self.marketPlaceId
|
||||
json["payment"] = self.payment.serializeToJSON()
|
||||
json["cardData"] = self.cardData
|
||||
|
||||
return json
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
//
|
||||
// Serializable.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by OA on 16.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// MARK: - Serializable
|
||||
|
||||
public protocol Serializable {
|
||||
|
||||
/// Serializes current object to generic JSON-Like dictionary
|
||||
func serializeToJSON() -> JSONDict
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Extension
|
||||
|
||||
public extension Serializable {
|
||||
|
||||
/// Serializes current object to data
|
||||
func serializeToData() throws -> Data {
|
||||
// let encoder = JSONEncoder()
|
||||
// let data = try encoder.encode(self.serializeToJSON())
|
||||
//
|
||||
// return data
|
||||
return try JSONSerialization.data(
|
||||
withJSONObject: self.serializeToJSON(),
|
||||
options: []
|
||||
)
|
||||
}
|
||||
|
||||
/// Serialzes to JSON-String
|
||||
func serializeToString() throws -> String {
|
||||
let data = try self.serializeToData()
|
||||
return String(data: data, encoding: .utf8)!
|
||||
}
|
||||
|
||||
/// Used for checking purposes if this object can be serialized without exception
|
||||
func assumeSerializes() throws {
|
||||
try serializeToString()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - JSONDict
|
||||
|
||||
public typealias JSONDict = [AnyHashable: AnyHashable]
|
||||
|
||||
//extension JSONDict {
|
||||
//
|
||||
// public mutating func add<T: RawRepresentable>(key: T, nullable value: JSONDict.Value?) where T.RawValue == JSONDict.Key {
|
||||
// if let value = value {
|
||||
// self.updateValue(value, forKey: key.rawValue)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
|
@ -0,0 +1,762 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 51;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
001B6B6B8EAA1CC9E76C93F2 /* Pods_PSCBOnlineSample_PSCBOnlineSampleUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 215AD129A382ED26BE4A9ADC /* Pods_PSCBOnlineSample_PSCBOnlineSampleUITests.framework */; };
|
||||
0ECA01D9254C88BF003DBD74 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ECA01D8254C88BF003DBD74 /* AppDelegate.swift */; };
|
||||
0ECA01DB254C88BF003DBD74 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ECA01DA254C88BF003DBD74 /* SceneDelegate.swift */; };
|
||||
0ECA01DD254C88BF003DBD74 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ECA01DC254C88BF003DBD74 /* ContentView.swift */; };
|
||||
0ECA01DF254C88C4003DBD74 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0ECA01DE254C88C4003DBD74 /* Assets.xcassets */; };
|
||||
0ECA01E2254C88C4003DBD74 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0ECA01E1254C88C4003DBD74 /* Preview Assets.xcassets */; };
|
||||
0ECA01E5254C88C4003DBD74 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0ECA01E3254C88C4003DBD74 /* LaunchScreen.storyboard */; };
|
||||
0ECA01F0254C88C5003DBD74 /* sdk_sampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ECA01EF254C88C5003DBD74 /* sdk_sampleTests.swift */; };
|
||||
0ECA01FB254C88C5003DBD74 /* sdk_sampleUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ECA01FA254C88C5003DBD74 /* sdk_sampleUITests.swift */; };
|
||||
0ECA0218254C8C12003DBD74 /* Podfile in Resources */ = {isa = PBXBuildFile; fileRef = 0ECA0217254C8C12003DBD74 /* Podfile */; };
|
||||
0ECA0237254C8DA0003DBD74 /* PaymentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ECA0236254C8DA0003DBD74 /* PaymentHandler.swift */; };
|
||||
37FA89195E22BD0C552D887A /* Pods_PSCBOnlineSampleTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 75E713AE69B50BE64C2D03E8 /* Pods_PSCBOnlineSampleTests.framework */; };
|
||||
69E05BEE77EA2E75B91678EE /* Pods_PSCBOnlineSample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ADAE0E73DFA819AE992A9C59 /* Pods_PSCBOnlineSample.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
0ECA01EC254C88C5003DBD74 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 0ECA01CD254C88BF003DBD74 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 0ECA01D4254C88BF003DBD74;
|
||||
remoteInfo = sdk.sample;
|
||||
};
|
||||
0ECA01F7254C88C5003DBD74 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 0ECA01CD254C88BF003DBD74 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 0ECA01D4254C88BF003DBD74;
|
||||
remoteInfo = sdk.sample;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
0ECA01D5254C88BF003DBD74 /* PSCBOnlineSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PSCBOnlineSample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0ECA01D8254C88BF003DBD74 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
0ECA01DA254C88BF003DBD74 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
|
||||
0ECA01DC254C88BF003DBD74 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||
0ECA01DE254C88C4003DBD74 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
0ECA01E1254C88C4003DBD74 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
||||
0ECA01E4254C88C4003DBD74 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
0ECA01E6254C88C4003DBD74 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
0ECA01EB254C88C5003DBD74 /* PSCBOnlineSampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PSCBOnlineSampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0ECA01EF254C88C5003DBD74 /* sdk_sampleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = sdk_sampleTests.swift; sourceTree = "<group>"; };
|
||||
0ECA01F1254C88C5003DBD74 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
0ECA01F6254C88C5003DBD74 /* PSCBOnlineSampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PSCBOnlineSampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0ECA01FA254C88C5003DBD74 /* sdk_sampleUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = sdk_sampleUITests.swift; sourceTree = "<group>"; };
|
||||
0ECA01FC254C88C5003DBD74 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
0ECA020B254C8902003DBD74 /* sdk.sample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = sdk.sample.entitlements; sourceTree = "<group>"; };
|
||||
0ECA0217254C8C12003DBD74 /* Podfile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Podfile; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
|
||||
0ECA0236254C8DA0003DBD74 /* PaymentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentHandler.swift; sourceTree = "<group>"; };
|
||||
215AD129A382ED26BE4A9ADC /* Pods_PSCBOnlineSample_PSCBOnlineSampleUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PSCBOnlineSample_PSCBOnlineSampleUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
2EAAA258959A1F5D92CFD851 /* Pods-PSCBOnlineSample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PSCBOnlineSample.release.xcconfig"; path = "Target Support Files/Pods-PSCBOnlineSample/Pods-PSCBOnlineSample.release.xcconfig"; sourceTree = "<group>"; };
|
||||
3E1FFD5E11C6E53BAB8BDD2B /* Pods-PSCBOnlineSample-PSCBOnlineSampleUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PSCBOnlineSample-PSCBOnlineSampleUITests.release.xcconfig"; path = "Target Support Files/Pods-PSCBOnlineSample-PSCBOnlineSampleUITests/Pods-PSCBOnlineSample-PSCBOnlineSampleUITests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
597562929002737E312BE5A9 /* Pods-PSCBOnlineSample-PSCBOnlineSampleUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PSCBOnlineSample-PSCBOnlineSampleUITests.debug.xcconfig"; path = "Target Support Files/Pods-PSCBOnlineSample-PSCBOnlineSampleUITests/Pods-PSCBOnlineSample-PSCBOnlineSampleUITests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
5D25A9250438F9C8AA6153F8 /* Pods-PSCBOnlineSample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PSCBOnlineSample.debug.xcconfig"; path = "Target Support Files/Pods-PSCBOnlineSample/Pods-PSCBOnlineSample.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
75E713AE69B50BE64C2D03E8 /* Pods_PSCBOnlineSampleTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PSCBOnlineSampleTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
ADAE0E73DFA819AE992A9C59 /* Pods_PSCBOnlineSample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PSCBOnlineSample.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
AE94091A3CE7B540776F6146 /* Pods-PSCBOnlineSampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PSCBOnlineSampleTests.release.xcconfig"; path = "Target Support Files/Pods-PSCBOnlineSampleTests/Pods-PSCBOnlineSampleTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
EE4EA7D50047330E553B55B6 /* Pods-PSCBOnlineSampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PSCBOnlineSampleTests.debug.xcconfig"; path = "Target Support Files/Pods-PSCBOnlineSampleTests/Pods-PSCBOnlineSampleTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
0ECA01D2254C88BF003DBD74 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
69E05BEE77EA2E75B91678EE /* Pods_PSCBOnlineSample.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
0ECA01E8254C88C5003DBD74 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
37FA89195E22BD0C552D887A /* Pods_PSCBOnlineSampleTests.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
0ECA01F3254C88C5003DBD74 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
001B6B6B8EAA1CC9E76C93F2 /* Pods_PSCBOnlineSample_PSCBOnlineSampleUITests.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
0ECA01CC254C88BF003DBD74 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0ECA0217254C8C12003DBD74 /* Podfile */,
|
||||
0ECA01D7254C88BF003DBD74 /* PSCBOnlineSample */,
|
||||
0ECA01EE254C88C5003DBD74 /* PSCBOnlineSampleTests */,
|
||||
0ECA01F9254C88C5003DBD74 /* PSCBOnlineSampleUITests */,
|
||||
0ECA01D6254C88BF003DBD74 /* Products */,
|
||||
A6BE523F775C844325774B50 /* Pods */,
|
||||
CC92252B44ABB68C5546B8DC /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0ECA01D6254C88BF003DBD74 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0ECA01D5254C88BF003DBD74 /* PSCBOnlineSample.app */,
|
||||
0ECA01EB254C88C5003DBD74 /* PSCBOnlineSampleTests.xctest */,
|
||||
0ECA01F6254C88C5003DBD74 /* PSCBOnlineSampleUITests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0ECA01D7254C88BF003DBD74 /* PSCBOnlineSample */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0ECA020B254C8902003DBD74 /* sdk.sample.entitlements */,
|
||||
0ECA01D8254C88BF003DBD74 /* AppDelegate.swift */,
|
||||
0ECA01DA254C88BF003DBD74 /* SceneDelegate.swift */,
|
||||
0ECA01DC254C88BF003DBD74 /* ContentView.swift */,
|
||||
0ECA01DE254C88C4003DBD74 /* Assets.xcassets */,
|
||||
0ECA01E3254C88C4003DBD74 /* LaunchScreen.storyboard */,
|
||||
0ECA01E6254C88C4003DBD74 /* Info.plist */,
|
||||
0ECA01E0254C88C4003DBD74 /* Preview Content */,
|
||||
0ECA0236254C8DA0003DBD74 /* PaymentHandler.swift */,
|
||||
);
|
||||
path = PSCBOnlineSample;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0ECA01E0254C88C4003DBD74 /* Preview Content */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0ECA01E1254C88C4003DBD74 /* Preview Assets.xcassets */,
|
||||
);
|
||||
path = "Preview Content";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0ECA01EE254C88C5003DBD74 /* PSCBOnlineSampleTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0ECA01EF254C88C5003DBD74 /* sdk_sampleTests.swift */,
|
||||
0ECA01F1254C88C5003DBD74 /* Info.plist */,
|
||||
);
|
||||
path = PSCBOnlineSampleTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0ECA01F9254C88C5003DBD74 /* PSCBOnlineSampleUITests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0ECA01FA254C88C5003DBD74 /* sdk_sampleUITests.swift */,
|
||||
0ECA01FC254C88C5003DBD74 /* Info.plist */,
|
||||
);
|
||||
path = PSCBOnlineSampleUITests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A6BE523F775C844325774B50 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5D25A9250438F9C8AA6153F8 /* Pods-PSCBOnlineSample.debug.xcconfig */,
|
||||
2EAAA258959A1F5D92CFD851 /* Pods-PSCBOnlineSample.release.xcconfig */,
|
||||
597562929002737E312BE5A9 /* Pods-PSCBOnlineSample-PSCBOnlineSampleUITests.debug.xcconfig */,
|
||||
3E1FFD5E11C6E53BAB8BDD2B /* Pods-PSCBOnlineSample-PSCBOnlineSampleUITests.release.xcconfig */,
|
||||
EE4EA7D50047330E553B55B6 /* Pods-PSCBOnlineSampleTests.debug.xcconfig */,
|
||||
AE94091A3CE7B540776F6146 /* Pods-PSCBOnlineSampleTests.release.xcconfig */,
|
||||
);
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CC92252B44ABB68C5546B8DC /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
ADAE0E73DFA819AE992A9C59 /* Pods_PSCBOnlineSample.framework */,
|
||||
215AD129A382ED26BE4A9ADC /* Pods_PSCBOnlineSample_PSCBOnlineSampleUITests.framework */,
|
||||
75E713AE69B50BE64C2D03E8 /* Pods_PSCBOnlineSampleTests.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
0ECA01D4254C88BF003DBD74 /* PSCBOnlineSample */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 0ECA01FF254C88C5003DBD74 /* Build configuration list for PBXNativeTarget "PSCBOnlineSample" */;
|
||||
buildPhases = (
|
||||
CD6C55176C28DD5EC847748D /* [CP] Check Pods Manifest.lock */,
|
||||
0ECA01D1254C88BF003DBD74 /* Sources */,
|
||||
0ECA01D2254C88BF003DBD74 /* Frameworks */,
|
||||
0ECA01D3254C88BF003DBD74 /* Resources */,
|
||||
1CCC3026FF4B068D24933916 /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = PSCBOnlineSample;
|
||||
productName = sdk.sample;
|
||||
productReference = 0ECA01D5254C88BF003DBD74 /* PSCBOnlineSample.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
0ECA01EA254C88C5003DBD74 /* PSCBOnlineSampleTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 0ECA0202254C88C5003DBD74 /* Build configuration list for PBXNativeTarget "PSCBOnlineSampleTests" */;
|
||||
buildPhases = (
|
||||
143B1BD2DA6C604E39332B78 /* [CP] Check Pods Manifest.lock */,
|
||||
0ECA01E7254C88C5003DBD74 /* Sources */,
|
||||
0ECA01E8254C88C5003DBD74 /* Frameworks */,
|
||||
0ECA01E9254C88C5003DBD74 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
0ECA01ED254C88C5003DBD74 /* PBXTargetDependency */,
|
||||
);
|
||||
name = PSCBOnlineSampleTests;
|
||||
productName = sdk.sampleTests;
|
||||
productReference = 0ECA01EB254C88C5003DBD74 /* PSCBOnlineSampleTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
0ECA01F5254C88C5003DBD74 /* PSCBOnlineSampleUITests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 0ECA0205254C88C5003DBD74 /* Build configuration list for PBXNativeTarget "PSCBOnlineSampleUITests" */;
|
||||
buildPhases = (
|
||||
A1AABD89A7AA5EFA1FDE3606 /* [CP] Check Pods Manifest.lock */,
|
||||
0ECA01F2254C88C5003DBD74 /* Sources */,
|
||||
0ECA01F3254C88C5003DBD74 /* Frameworks */,
|
||||
0ECA01F4254C88C5003DBD74 /* Resources */,
|
||||
6BAD522C988953C7BFCC5A17 /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
0ECA01F8254C88C5003DBD74 /* PBXTargetDependency */,
|
||||
);
|
||||
name = PSCBOnlineSampleUITests;
|
||||
productName = sdk.sampleUITests;
|
||||
productReference = 0ECA01F6254C88C5003DBD74 /* PSCBOnlineSampleUITests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.ui-testing";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
0ECA01CD254C88BF003DBD74 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 1210;
|
||||
LastUpgradeCheck = 1210;
|
||||
TargetAttributes = {
|
||||
0ECA01D4254C88BF003DBD74 = {
|
||||
CreatedOnToolsVersion = 12.1;
|
||||
};
|
||||
0ECA01EA254C88C5003DBD74 = {
|
||||
CreatedOnToolsVersion = 12.1;
|
||||
TestTargetID = 0ECA01D4254C88BF003DBD74;
|
||||
};
|
||||
0ECA01F5254C88C5003DBD74 = {
|
||||
CreatedOnToolsVersion = 12.1;
|
||||
TestTargetID = 0ECA01D4254C88BF003DBD74;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 0ECA01D0254C88BF003DBD74 /* Build configuration list for PBXProject "PSCBOnlineSample" */;
|
||||
compatibilityVersion = "Xcode 9.3";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 0ECA01CC254C88BF003DBD74;
|
||||
productRefGroup = 0ECA01D6254C88BF003DBD74 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
0ECA01D4254C88BF003DBD74 /* PSCBOnlineSample */,
|
||||
0ECA01EA254C88C5003DBD74 /* PSCBOnlineSampleTests */,
|
||||
0ECA01F5254C88C5003DBD74 /* PSCBOnlineSampleUITests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
0ECA01D3254C88BF003DBD74 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0ECA01E5254C88C4003DBD74 /* LaunchScreen.storyboard in Resources */,
|
||||
0ECA01E2254C88C4003DBD74 /* Preview Assets.xcassets in Resources */,
|
||||
0ECA0218254C8C12003DBD74 /* Podfile in Resources */,
|
||||
0ECA01DF254C88C4003DBD74 /* Assets.xcassets in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
0ECA01E9254C88C5003DBD74 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
0ECA01F4254C88C5003DBD74 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
143B1BD2DA6C604E39332B78 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-PSCBOnlineSampleTests-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
1CCC3026FF4B068D24933916 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-PSCBOnlineSample/Pods-PSCBOnlineSample-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-PSCBOnlineSample/Pods-PSCBOnlineSample-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PSCBOnlineSample/Pods-PSCBOnlineSample-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
6BAD522C988953C7BFCC5A17 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-PSCBOnlineSample-PSCBOnlineSampleUITests/Pods-PSCBOnlineSample-PSCBOnlineSampleUITests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-PSCBOnlineSample-PSCBOnlineSampleUITests/Pods-PSCBOnlineSample-PSCBOnlineSampleUITests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PSCBOnlineSample-PSCBOnlineSampleUITests/Pods-PSCBOnlineSample-PSCBOnlineSampleUITests-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
A1AABD89A7AA5EFA1FDE3606 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-PSCBOnlineSample-PSCBOnlineSampleUITests-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
CD6C55176C28DD5EC847748D /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-PSCBOnlineSample-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
0ECA01D1254C88BF003DBD74 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0ECA01D9254C88BF003DBD74 /* AppDelegate.swift in Sources */,
|
||||
0ECA01DB254C88BF003DBD74 /* SceneDelegate.swift in Sources */,
|
||||
0ECA01DD254C88BF003DBD74 /* ContentView.swift in Sources */,
|
||||
0ECA0237254C8DA0003DBD74 /* PaymentHandler.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
0ECA01E7254C88C5003DBD74 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0ECA01F0254C88C5003DBD74 /* sdk_sampleTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
0ECA01F2254C88C5003DBD74 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0ECA01FB254C88C5003DBD74 /* sdk_sampleUITests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
0ECA01ED254C88C5003DBD74 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 0ECA01D4254C88BF003DBD74 /* PSCBOnlineSample */;
|
||||
targetProxy = 0ECA01EC254C88C5003DBD74 /* PBXContainerItemProxy */;
|
||||
};
|
||||
0ECA01F8254C88C5003DBD74 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 0ECA01D4254C88BF003DBD74 /* PSCBOnlineSample */;
|
||||
targetProxy = 0ECA01F7254C88C5003DBD74 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
0ECA01E3254C88C4003DBD74 /* LaunchScreen.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
0ECA01E4254C88C4003DBD74 /* Base */,
|
||||
);
|
||||
name = LaunchScreen.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
0ECA01FD254C88C5003DBD74 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.1;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
0ECA01FE254C88C5003DBD74 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.1;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
0ECA0200254C88C5003DBD74 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 5D25A9250438F9C8AA6153F8 /* Pods-PSCBOnlineSample.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"PSCBOnlineSample/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = 46N426YCGP;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
INFOPLIST_FILE = PSCBOnlineSample/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "ru.pscb.ios-lib-sample";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
0ECA0201254C88C5003DBD74 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 2EAAA258959A1F5D92CFD851 /* Pods-PSCBOnlineSample.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"PSCBOnlineSample/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = 46N426YCGP;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
INFOPLIST_FILE = PSCBOnlineSample/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "ru.pscb.ios-lib-sample";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
0ECA0203254C88C5003DBD74 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = EE4EA7D50047330E553B55B6 /* Pods-PSCBOnlineSampleTests.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 46N426YCGP;
|
||||
INFOPLIST_FILE = PSCBOnlineSampleTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "ru.pscb.sdk-sampleTests";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PSCBOnlineSample.app/PSCBOnlineSample";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
0ECA0204254C88C5003DBD74 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = AE94091A3CE7B540776F6146 /* Pods-PSCBOnlineSampleTests.release.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 46N426YCGP;
|
||||
INFOPLIST_FILE = PSCBOnlineSampleTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "ru.pscb.sdk-sampleTests";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PSCBOnlineSample.app/PSCBOnlineSample";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
0ECA0206254C88C5003DBD74 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 597562929002737E312BE5A9 /* Pods-PSCBOnlineSample-PSCBOnlineSampleUITests.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 46N426YCGP;
|
||||
INFOPLIST_FILE = PSCBOnlineSampleUITests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "ru.pscb.sdk-sampleUITests";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TEST_TARGET_NAME = sdk.sample;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
0ECA0207254C88C5003DBD74 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 3E1FFD5E11C6E53BAB8BDD2B /* Pods-PSCBOnlineSample-PSCBOnlineSampleUITests.release.xcconfig */;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 46N426YCGP;
|
||||
INFOPLIST_FILE = PSCBOnlineSampleUITests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "ru.pscb.sdk-sampleUITests";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TEST_TARGET_NAME = sdk.sample;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
0ECA01D0254C88BF003DBD74 /* Build configuration list for PBXProject "PSCBOnlineSample" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
0ECA01FD254C88C5003DBD74 /* Debug */,
|
||||
0ECA01FE254C88C5003DBD74 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
0ECA01FF254C88C5003DBD74 /* Build configuration list for PBXNativeTarget "PSCBOnlineSample" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
0ECA0200254C88C5003DBD74 /* Debug */,
|
||||
0ECA0201254C88C5003DBD74 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
0ECA0202254C88C5003DBD74 /* Build configuration list for PBXNativeTarget "PSCBOnlineSampleTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
0ECA0203254C88C5003DBD74 /* Debug */,
|
||||
0ECA0204254C88C5003DBD74 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
0ECA0205254C88C5003DBD74 /* Build configuration list for PBXNativeTarget "PSCBOnlineSampleUITests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
0ECA0206254C88C5003DBD74 /* Debug */,
|
||||
0ECA0207254C88C5003DBD74 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 0ECA01CD254C88BF003DBD74 /* Project object */;
|
||||
}
|
7
PSCBOnlineSample/PSCBOnlineSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
PSCBOnlineSample/PSCBOnlineSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
Binary file not shown.
|
@ -0,0 +1,98 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1210"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "0ECA01D4254C88BF003DBD74"
|
||||
BuildableName = "PSCBOnlineSample.app"
|
||||
BlueprintName = "PSCBOnlineSample"
|
||||
ReferencedContainer = "container:PSCBOnlineSample.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "0ECA01EA254C88C5003DBD74"
|
||||
BuildableName = "PSCBOnlineSampleTests.xctest"
|
||||
BlueprintName = "PSCBOnlineSampleTests"
|
||||
ReferencedContainer = "container:PSCBOnlineSample.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "0ECA01F5254C88C5003DBD74"
|
||||
BuildableName = "PSCBOnlineSampleUITests.xctest"
|
||||
BlueprintName = "PSCBOnlineSampleUITests"
|
||||
ReferencedContainer = "container:PSCBOnlineSample.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "0ECA01D4254C88BF003DBD74"
|
||||
BuildableName = "PSCBOnlineSample.app"
|
||||
BlueprintName = "PSCBOnlineSample"
|
||||
ReferencedContainer = "container:PSCBOnlineSample.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "0ECA01D4254C88BF003DBD74"
|
||||
BuildableName = "PSCBOnlineSample.app"
|
||||
BlueprintName = "PSCBOnlineSample"
|
||||
ReferencedContainer = "container:PSCBOnlineSample.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>PSCBOnlineSample.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>sdk.sample.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>4</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>0ECA01D4254C88BF003DBD74</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>0ECA01EA254C88C5003DBD74</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>0ECA01F5254C88C5003DBD74</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:PSCBOnlineSample.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.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>
|
BIN
PSCBOnlineSample/PSCBOnlineSample.xcworkspace/xcuserdata/oa.xcuserdatad/UserInterfaceState.xcuserstate
generated
Normal file
BIN
PSCBOnlineSample/PSCBOnlineSample.xcworkspace/xcuserdata/oa.xcuserdatad/UserInterfaceState.xcuserstate
generated
Normal file
Binary file not shown.
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// AppDelegate.swift
|
||||
// sdk.sample
|
||||
//
|
||||
// Created by OA on 30.10.2020.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@main
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
// Override point for customization after application launch.
|
||||
return true
|
||||
}
|
||||
|
||||
// MARK: UISceneSession Lifecycle
|
||||
|
||||
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
|
||||
// Called when a new scene session is being created.
|
||||
// Use this method to select a configuration to create the new scene with.
|
||||
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
|
||||
}
|
||||
|
||||
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
|
||||
// Called when the user discards a scene session.
|
||||
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
|
||||
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "60x60"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "60x60"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "76x76"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "76x76"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "83.5x83.5"
|
||||
},
|
||||
{
|
||||
"idiom" : "ios-marketing",
|
||||
"scale" : "1x",
|
||||
"size" : "1024x1024"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="53" y="375"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
|
@ -0,0 +1,124 @@
|
|||
//
|
||||
// ContentView.swift
|
||||
// sdk.sample
|
||||
//
|
||||
// Created by Antonov Ilia on 30.10.2020.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import PassKit
|
||||
import PSCBOnline
|
||||
|
||||
struct ContentView: View {
|
||||
|
||||
static let dateFormatter: DateFormatter = {
|
||||
let df = DateFormatter()
|
||||
df.dateFormat = "yyMMddhhmmss"
|
||||
|
||||
return df
|
||||
}()
|
||||
|
||||
let paymentMethods = ["Apple pay", "Credit Card"]
|
||||
let amount = Decimal(155.35)
|
||||
let handler = PaymentHandler()
|
||||
|
||||
@State private var paymentMethod = 0
|
||||
@State private var showAlert = false
|
||||
@State private var paymentState: PaymentStatus = .unknown
|
||||
@State private var lastOrderId: String?
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
if (self.lastOrderId != nil) {
|
||||
Text("Last order ID = \(self.lastOrderId!)")
|
||||
} else {
|
||||
Text("No payments has been made yet")
|
||||
}
|
||||
|
||||
Picker(selection: $paymentMethod, label: Text("Which way would you like to pay?")) {
|
||||
ForEach(0 ..< paymentMethods.count) {
|
||||
Text(self.paymentMethods[$0])
|
||||
}
|
||||
}
|
||||
|
||||
Button(action: {
|
||||
self.handlePayment()
|
||||
}) {
|
||||
HStack {
|
||||
Text("Pay!")
|
||||
.fontWeight(.semibold)
|
||||
.font(.title)
|
||||
}
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
.padding()
|
||||
.foregroundColor(.white)
|
||||
.background(Color(.black))
|
||||
.cornerRadius(40)
|
||||
.alert(isPresented: self.$showAlert, content: {
|
||||
Alert(
|
||||
title: Text("Payment status"),
|
||||
message: Text("\(String(describing: self.paymentState))"),
|
||||
dismissButton: .default(Text("OK"))
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handlePayment() {
|
||||
let now = Self.dateFormatter.string(from: Date())
|
||||
|
||||
// Payment info
|
||||
let payment = Payment(amount: self.amount, orderId: "XC-\(now)")
|
||||
|
||||
if (self.paymentMethod == 0) {
|
||||
payByApplePay(payment)
|
||||
}
|
||||
|
||||
if (self.paymentMethod == 1) {
|
||||
payByCreditCard(payment)
|
||||
}
|
||||
}
|
||||
|
||||
private func payByApplePay(_ payment: Payment) {
|
||||
let item = PKPaymentSummaryItem(
|
||||
label: "Sample",
|
||||
amount: NSDecimalNumber(decimal: self.amount)
|
||||
)
|
||||
|
||||
self.handler.applePay(payment, items: [item]) { (status) in
|
||||
if status == .success {
|
||||
self.lastOrderId = payment.orderId
|
||||
print("Meow")
|
||||
} else {
|
||||
print("ArghhH!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func payByCreditCard(_ payment: Payment) {
|
||||
// Card info
|
||||
let card = CardData(
|
||||
pan: "4761 1200 10000492",
|
||||
expiryYear: 2022,
|
||||
expiryMonth: 11,
|
||||
cvCode: "533"
|
||||
)
|
||||
|
||||
self.handler.creditCard(
|
||||
payment,
|
||||
card: card!,
|
||||
completionHandler: { (status) in
|
||||
self.showAlert = true
|
||||
self.paymentState = status
|
||||
print("Success?: \(status)")
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct ContentView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ContentView()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIApplicationSceneManifest</key>
|
||||
<dict>
|
||||
<key>UIApplicationSupportsMultipleScenes</key>
|
||||
<false/>
|
||||
<key>UISceneConfigurations</key>
|
||||
<dict>
|
||||
<key>UIWindowSceneSessionRoleApplication</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UISceneConfigurationName</key>
|
||||
<string>Default Configuration</string>
|
||||
<key>UISceneDelegateClassName</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,129 @@
|
|||
//
|
||||
// PaymentHandler.swift
|
||||
// sdk.sample
|
||||
//
|
||||
// Created by Antonov Ilia on 30.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import PassKit
|
||||
import PSCBOnline
|
||||
|
||||
// MARK: - Payment status
|
||||
public enum PaymentStatus {
|
||||
case success
|
||||
case failure
|
||||
case unknown
|
||||
}
|
||||
|
||||
public typealias PaymentCompletionHandler = (PaymentStatus) -> Void
|
||||
|
||||
// MARK: - Payment hander
|
||||
public class PaymentHandler: NSObject {
|
||||
|
||||
// Initialize OOS API Client
|
||||
static let client = PSCBOnlineClient(environment: .sandbox, marketPlaceId: "288747332", signingKey: "111111")
|
||||
|
||||
// Current payment status
|
||||
private var paymentStatus: PaymentStatus = .unknown
|
||||
private var completionHandler: PaymentCompletionHandler?
|
||||
|
||||
private var authorizationController: PKPaymentAuthorizationController?
|
||||
private var payment: Payment?
|
||||
|
||||
// MARK: - Payment handlers
|
||||
func applePay(_ payment: Payment, items: [PKPaymentSummaryItem],
|
||||
completionHandler: @escaping PaymentCompletionHandler) {
|
||||
let status = PSCBAPI.canMakePayments()
|
||||
print("status: \(String(describing: status))")
|
||||
|
||||
// Create PKPayment instance
|
||||
let pk = PSCBAPI.makePaymentRequest(items: items)
|
||||
|
||||
self.completionHandler = completionHandler
|
||||
self.payment = payment
|
||||
|
||||
authorizationController = PKPaymentAuthorizationController(paymentRequest: pk)
|
||||
authorizationController?.delegate = self
|
||||
authorizationController?.present(completion: { presented in
|
||||
if presented {
|
||||
print("Controller presented")
|
||||
} else {
|
||||
print("Controller could not be presented")
|
||||
completionHandler(.unknown)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func creditCard(_ payment: Payment, card: CardData,
|
||||
completionHandler: @escaping PaymentCompletionHandler) {
|
||||
let client = Self.client
|
||||
|
||||
do {
|
||||
// Create request token
|
||||
let request = try client.makeRequestWithCardData(card: card, payment: payment)
|
||||
|
||||
// Send request to backend
|
||||
client.send(request, responseHandler: { (error, response) in
|
||||
guard nil == error else {
|
||||
print("Error sending request: \(String(describing: error))")
|
||||
|
||||
completionHandler(.failure)
|
||||
return
|
||||
}
|
||||
|
||||
print("Successful request:")
|
||||
print(response!)
|
||||
|
||||
completionHandler(.success)
|
||||
})
|
||||
} catch {
|
||||
print("Unable to create request: \(String(describing: error))")
|
||||
completionHandler(.failure)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Conforming to PKPaymentAuthorizationControllerDelegate
|
||||
extension PaymentHandler: PKPaymentAuthorizationControllerDelegate {
|
||||
|
||||
public func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController,
|
||||
didAuthorizePayment payment: PKPayment,
|
||||
handler completion: @escaping (PKPaymentAuthorizationResult) -> Void) {
|
||||
// Payment authorized. Make request to backend
|
||||
// Create request token
|
||||
let request = try! Self.client.makeRequestWithPayment(pkPayment: payment, payment: self.payment!)
|
||||
|
||||
Self.client.send(request, responseHandler: { (error, response) in
|
||||
if (error == nil && response != nil) {
|
||||
self.paymentStatus = .success
|
||||
|
||||
completion(PKPaymentAuthorizationResult(status: .success, errors: nil))
|
||||
} else {
|
||||
print("Error sending payment: \(String(describing: error))")
|
||||
self.paymentStatus = .failure
|
||||
|
||||
completion(PKPaymentAuthorizationResult(status: .failure, errors: nil))
|
||||
}
|
||||
|
||||
self.completionHandler!(self.paymentStatus)
|
||||
})
|
||||
}
|
||||
|
||||
public func paymentAuthorizationControllerDidFinish(_ controller: PKPaymentAuthorizationController) {
|
||||
controller.dismiss {
|
||||
DispatchQueue.main.async {
|
||||
print("Did finish with status: \(self.paymentStatus)")
|
||||
if self.paymentStatus == .success {
|
||||
self.completionHandler!(.success)
|
||||
} else {
|
||||
self.completionHandler!(.failure)
|
||||
}
|
||||
|
||||
self.paymentStatus = .unknown
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
//
|
||||
// SceneDelegate.swift
|
||||
// sdk.sample
|
||||
//
|
||||
// Created by OA on 30.10.2020.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SwiftUI
|
||||
|
||||
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
|
||||
var window: UIWindow?
|
||||
|
||||
|
||||
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
||||
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
|
||||
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
|
||||
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
|
||||
|
||||
// Create the SwiftUI view that provides the window contents.
|
||||
let contentView = ContentView()
|
||||
|
||||
// Use a UIHostingController as window root view controller.
|
||||
if let windowScene = scene as? UIWindowScene {
|
||||
let window = UIWindow(windowScene: windowScene)
|
||||
window.rootViewController = UIHostingController(rootView: contentView)
|
||||
self.window = window
|
||||
window.makeKeyAndVisible()
|
||||
}
|
||||
}
|
||||
|
||||
func sceneDidDisconnect(_ scene: UIScene) {
|
||||
// Called as the scene is being released by the system.
|
||||
// This occurs shortly after the scene enters the background, or when its session is discarded.
|
||||
// Release any resources associated with this scene that can be re-created the next time the scene connects.
|
||||
// The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
|
||||
}
|
||||
|
||||
func sceneDidBecomeActive(_ scene: UIScene) {
|
||||
// Called when the scene has moved from an inactive state to an active state.
|
||||
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
|
||||
}
|
||||
|
||||
func sceneWillResignActive(_ scene: UIScene) {
|
||||
// Called when the scene will move from an active state to an inactive state.
|
||||
// This may occur due to temporary interruptions (ex. an incoming phone call).
|
||||
}
|
||||
|
||||
func sceneWillEnterForeground(_ scene: UIScene) {
|
||||
// Called as the scene transitions from the background to the foreground.
|
||||
// Use this method to undo the changes made on entering the background.
|
||||
}
|
||||
|
||||
func sceneDidEnterBackground(_ scene: UIScene) {
|
||||
// Called as the scene transitions from the foreground to the background.
|
||||
// Use this method to save data, release shared resources, and store enough scene-specific state information
|
||||
// to restore the scene back to its current state.
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.developer.associated-domains</key>
|
||||
<array/>
|
||||
<key>com.apple.developer.in-app-payments</key>
|
||||
<array>
|
||||
<string>merchant.pscb.pay</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,33 @@
|
|||
//
|
||||
// sdk_sampleTests.swift
|
||||
// sdk.sampleTests
|
||||
//
|
||||
// Created by OA on 30.10.2020.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import sdk_sample
|
||||
|
||||
class sdk_sampleTests: XCTestCase {
|
||||
|
||||
override func setUpWithError() throws {
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
override func tearDownWithError() throws {
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
func testExample() throws {
|
||||
// This is an example of a functional test case.
|
||||
// Use XCTAssert and related functions to verify your tests produce the correct results.
|
||||
}
|
||||
|
||||
func testPerformanceExample() throws {
|
||||
// This is an example of a performance test case.
|
||||
self.measure {
|
||||
// Put the code you want to measure the time of here.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,42 @@
|
|||
//
|
||||
// sdk_sampleUITests.swift
|
||||
// sdk.sampleUITests
|
||||
//
|
||||
// Created by OA on 30.10.2020.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
|
||||
class sdk_sampleUITests: XCTestCase {
|
||||
|
||||
override func setUpWithError() throws {
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
|
||||
// In UI tests it is usually best to stop immediately when a failure occurs.
|
||||
continueAfterFailure = false
|
||||
|
||||
// In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
|
||||
}
|
||||
|
||||
override func tearDownWithError() throws {
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
func testExample() throws {
|
||||
// UI tests must launch the application that they test.
|
||||
let app = XCUIApplication()
|
||||
app.launch()
|
||||
|
||||
// Use recording to get started writing UI tests.
|
||||
// Use XCTAssert and related functions to verify your tests produce the correct results.
|
||||
}
|
||||
|
||||
func testLaunchPerformance() throws {
|
||||
if #available(macOS 10.15, iOS 13.0, tvOS 13.0, *) {
|
||||
// This measures how long it takes to launch your application.
|
||||
measure(metrics: [XCTApplicationLaunchMetric()]) {
|
||||
XCUIApplication().launch()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
PODS:
|
||||
- PSCBOnline (1.0.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
- PSCBOnline (from `https://bitbucket.org/dev_ai/pscbonline.git`, tag `1.0.1`)
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
PSCBOnline:
|
||||
:git: https://bitbucket.org/dev_ai/pscbonline.git
|
||||
:tag: 1.0.1
|
||||
|
||||
CHECKOUT OPTIONS:
|
||||
PSCBOnline:
|
||||
:git: https://bitbucket.org/dev_ai/pscbonline.git
|
||||
:tag: 1.0.1
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
PSCBOnline: 0fe49a5f94b13c88b422774d9225449810f6a437
|
||||
|
||||
PODFILE CHECKSUM: 56239c9e9e41b37a479ce9620a24a65d5832a2a1
|
||||
|
||||
COCOAPODS: 1.10.0
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"name": "PSCBOnline",
|
||||
"version": "1.0.0",
|
||||
"summary": "An iOS SDK for PSCB Online (OOS) acquiring protocol.",
|
||||
"description": "An implementation of PSCB-Online (oos.pscb.ru) acquiring protocol for iOS platforms.",
|
||||
"homepage": "https://oos.pscb.ru/",
|
||||
"license": {
|
||||
"type": "PSCB",
|
||||
"file": "LICENSE.txt"
|
||||
},
|
||||
"authors": {
|
||||
"Antonov Ilia": "antilya@gmail.com"
|
||||
},
|
||||
"platforms": {
|
||||
"ios": "10.0"
|
||||
},
|
||||
"source": {
|
||||
"git": "https://bitbucket.org/dev_ai/oos-ios.git",
|
||||
"tag": "1.0.0"
|
||||
},
|
||||
"source_files": "PSCBOnline/**/*.{h,m,swift}",
|
||||
"exclude_files": "",
|
||||
"swift_versions": "5.3",
|
||||
"swift_version": "5.3"
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
PODS:
|
||||
- PSCBOnline (1.0.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
- PSCBOnline (from `https://bitbucket.org/dev_ai/pscbonline.git`, tag `1.0.1`)
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
PSCBOnline:
|
||||
:git: https://bitbucket.org/dev_ai/pscbonline.git
|
||||
:tag: 1.0.1
|
||||
|
||||
CHECKOUT OPTIONS:
|
||||
PSCBOnline:
|
||||
:git: https://bitbucket.org/dev_ai/pscbonline.git
|
||||
:tag: 1.0.1
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
PSCBOnline: 0fe49a5f94b13c88b422774d9225449810f6a437
|
||||
|
||||
PODFILE CHECKSUM: 56239c9e9e41b37a479ce9620a24a65d5832a2a1
|
||||
|
||||
COCOAPODS: 1.10.0
|
|
@ -0,0 +1 @@
|
|||
LICENSE BE HERE
|
|
@ -0,0 +1,18 @@
|
|||
//
|
||||
// PSCBOnline.h
|
||||
// PSCBOnline
|
||||
//
|
||||
// Created by Antonov Ilia on 16.10.2020.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
//! Project version number for PSCBOnline.
|
||||
FOUNDATION_EXPORT double PSCBOnlineVersionNumber;
|
||||
|
||||
//! Project version string for PSCBOnline.
|
||||
FOUNDATION_EXPORT const unsigned char PSCBOnlineVersionString[];
|
||||
|
||||
// In this header, you should import all the public headers of your framework using statements like #import <PSCBOnline/PublicHeader.h>
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// String.swift
|
||||
//
|
||||
//
|
||||
// Created by AntonovIA on 12.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension String {
|
||||
|
||||
private static let alphanumeric = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
|
||||
static func random(length: Int, allowedChars: String? = nil) -> String {
|
||||
let seq: String = ((allowedChars == nil) ? alphanumeric : allowedChars!) as String
|
||||
var rnd: String = ""
|
||||
|
||||
for _ in 0..<length {
|
||||
let randInt = arc4random_uniform(UInt32(seq.count))
|
||||
rnd += "\(seq[seq.index(seq.startIndex, offsetBy: Int(randInt))])"
|
||||
}
|
||||
|
||||
return rnd
|
||||
}
|
||||
|
||||
}
|
29
PSCBOnlineSample/Pods/PSCBOnline/PSCBOnline/Sources/Helpers/DigestHelper.swift
generated
Normal file
29
PSCBOnlineSample/Pods/PSCBOnline/PSCBOnline/Sources/Helpers/DigestHelper.swift
generated
Normal file
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// DigestHelper.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by Antonov Ilia on 28.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CommonCrypto
|
||||
|
||||
public struct DigestHelper {
|
||||
|
||||
public static func sha256String(_ string: String) -> String {
|
||||
let data = string.data(using: .utf8)!
|
||||
var hash = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
|
||||
var sign = ""
|
||||
|
||||
data.withUnsafeBytes {
|
||||
_ = CC_SHA256($0.baseAddress, CC_LONG(data.count), &hash)
|
||||
}
|
||||
|
||||
for byte in hash {
|
||||
sign += String(format: "%02x", UInt8(byte))
|
||||
}
|
||||
|
||||
return sign.lowercased()
|
||||
}
|
||||
|
||||
}
|
33
PSCBOnlineSample/Pods/PSCBOnline/PSCBOnline/Sources/Helpers/JSONDecoders.swift
generated
Normal file
33
PSCBOnlineSample/Pods/PSCBOnline/PSCBOnline/Sources/Helpers/JSONDecoders.swift
generated
Normal file
|
@ -0,0 +1,33 @@
|
|||
//
|
||||
// JSONDecoders.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by Antonov Ilia on 25.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
final public class JSONDecoders {
|
||||
|
||||
public static func iso8601DateAwareDecoder() -> JSONDecoder {
|
||||
return ISO8601DateAwareJSONDecoder()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - ISO8601 date aware JSON Decoder
|
||||
class ISO8601DateAwareJSONDecoder: JSONDecoder {
|
||||
|
||||
static internal let dateTimeFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
|
||||
|
||||
let dateFormatter: DateFormatter = DateFormatter()
|
||||
let calendar = Calendar.current
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
dateFormatter.dateFormat = Self.dateTimeFormat
|
||||
dateDecodingStrategy = .formatted(dateFormatter)
|
||||
}
|
||||
|
||||
}
|
86
PSCBOnlineSample/Pods/PSCBOnline/PSCBOnline/Sources/Helpers/RSAHelper.swift
generated
Normal file
86
PSCBOnlineSample/Pods/PSCBOnline/PSCBOnline/Sources/Helpers/RSAHelper.swift
generated
Normal file
|
@ -0,0 +1,86 @@
|
|||
//
|
||||
// RSAHelper.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by Antonov Ilia on 26.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum RSAKeyError: Error {
|
||||
|
||||
/// Thrown when provided public key is invalid
|
||||
case invalidKey
|
||||
|
||||
/// Thrown when encryption of message failed
|
||||
case encryption(OSStatus)
|
||||
|
||||
/// Thrown when unable to initialize `SecKey` with given key string
|
||||
case unmanaged(Unmanaged<CFError>)
|
||||
}
|
||||
|
||||
public final class RSAHelper {
|
||||
|
||||
internal static let key = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAPQsWyHaynwoc2tuMbengf1SFase9tPnwtPh4o1tR+94xsWztADdhhUaUBk/68ipaoZE8uSnM9UgdEPmOotFXyUCAwEAAQ=="
|
||||
|
||||
internal static var secKey: SecKey? = nil
|
||||
|
||||
static func initPSCBOnlinePublicKey() throws {
|
||||
// Treat as assert
|
||||
guard let keyData = Data(base64Encoded: key) else {
|
||||
print("Invalid key string: \(key)")
|
||||
throw RSAKeyError.invalidKey
|
||||
}
|
||||
|
||||
var attributes: CFDictionary {
|
||||
return [
|
||||
kSecAttrKeyType: kSecAttrKeyTypeRSA,
|
||||
kSecAttrKeyClass: kSecAttrKeyClassPublic,
|
||||
kSecAttrKeySizeInBits: 2048,
|
||||
kSecReturnPersistentRef: true
|
||||
] as CFDictionary
|
||||
}
|
||||
|
||||
var error: Unmanaged<CFError>? = nil
|
||||
guard let secKey = SecKeyCreateWithData(keyData as CFData, attributes, &error) else {
|
||||
print("Error creating a security key with \(String(describing: keyData))")
|
||||
print(error.debugDescription)
|
||||
throw RSAKeyError.unmanaged(error!)
|
||||
}
|
||||
|
||||
Self.secKey = secKey
|
||||
}
|
||||
|
||||
/// Encrypts given message with OOS public key.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - message: A message to encrypt.
|
||||
///
|
||||
/// - Returns: A base64 encoded string
|
||||
///
|
||||
/// - Throws: `RSAKeyError` type error
|
||||
public static func encryptEncodeBase64(message: String) throws -> String {
|
||||
// Initialize OOS public key
|
||||
if Self.secKey == nil {
|
||||
try Self.initPSCBOnlinePublicKey()
|
||||
}
|
||||
|
||||
// Initialize buffers
|
||||
let sKey = Self.secKey!
|
||||
let buff = [UInt8](message.utf8)
|
||||
|
||||
// Mutable encryption refs
|
||||
var size = SecKeyGetBlockSize(sKey)
|
||||
var kBuf = [UInt8](repeating: 0, count: size)
|
||||
|
||||
let status = SecKeyEncrypt(sKey, SecPadding.PKCS1, buff, buff.count, &kBuf, &size)
|
||||
|
||||
// Sanity check
|
||||
guard status == errSecSuccess else {
|
||||
throw RSAKeyError.encryption(status)
|
||||
}
|
||||
|
||||
return Data(bytes: kBuf, count: size).base64EncodedString()
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
//
|
||||
// CardData.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by Antonov Ilia on 21.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import PassKit
|
||||
|
||||
public enum CardDataError: Error {
|
||||
case invalidExiryDate(String)
|
||||
case invalidCvCode
|
||||
case invalidPan
|
||||
}
|
||||
|
||||
/// Billing info.
|
||||
/// Detailed card information
|
||||
public struct CardData {
|
||||
let pan: String
|
||||
let expiryYear: Int
|
||||
let expiryMonth: Int
|
||||
let cardholder: String?
|
||||
let cvCode: String
|
||||
|
||||
/// Constructs card data from all necessary for billing fields
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - pan: Card number
|
||||
/// - expiryYear: A full year number (e.g: `2020`). For production cannot be in the past
|
||||
/// - expiryMonth: A month number from 1 to 12.
|
||||
/// - cvCode: CVC/CVV number
|
||||
/// - cardholder: (Optional) Cardholder name in latin.
|
||||
///
|
||||
/// - Returns: optional instance of a new card. If validation fails returns nil
|
||||
public init?(pan: String, expiryYear: Int, expiryMonth: Int, cvCode: String, cardholder: String? = nil) {
|
||||
guard expiryMonth >= 1 && expiryMonth <= 12 else {
|
||||
print("Month can be between 1 and 12")
|
||||
return nil
|
||||
}
|
||||
|
||||
#if !DEBUG
|
||||
// todo check year + month in the past
|
||||
let currentYear = Calendar.current.component(.year, from: Date())
|
||||
guard expiryYear >= currentYear else {
|
||||
print("Year must be current or in the future")
|
||||
return nil
|
||||
}
|
||||
#endif
|
||||
|
||||
self.pan = pan
|
||||
self.expiryMonth = expiryMonth
|
||||
self.expiryYear = expiryYear
|
||||
self.cvCode = cvCode
|
||||
self.cardholder = cardholder
|
||||
}
|
||||
|
||||
/// - Returns: A last 2 digits of the expiry year
|
||||
public func getExpYearString() -> String {
|
||||
return String(String(expiryYear).dropFirst(2))
|
||||
}
|
||||
|
||||
/// - Returns: A zero padded expiry month string
|
||||
public func getExpMonthString() -> String {
|
||||
return expiryMonth < 10 ? "0\(self.expiryMonth)" : String(self.expiryMonth)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension CardData {
|
||||
|
||||
internal static let pubKey: Data = {
|
||||
let key = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAPQsWyHaynwoc2tuMbengf1SFase9tPnwtPh4o1tR+94xsWztADdhhUaUBk/68ipaoZE8uSnM9UgdEPmOotFXyUCAwEAAQ=="
|
||||
|
||||
return Data(base64Encoded: key)!
|
||||
}()
|
||||
|
||||
|
||||
/// Produces a cryptogram string from given `CardData`
|
||||
/// See: https://docs.pscb.ru/oos/shpa.html#shlyuz-prozrachnoj-avtorizacii-sozdanie-platezha-otvet
|
||||
///
|
||||
/// - Returns: a Base64 encoded cryptogram string
|
||||
public func toCryptgramString() throws -> String {
|
||||
let month = self.getExpMonthString()
|
||||
let year = self.getExpYearString()
|
||||
let joinedString = "\(self.pan)|\(month)|\(year)|\(cvCode)\(self.cardholder ?? "")"
|
||||
let base64Encode = try RSAHelper.encryptEncodeBase64(message: joinedString)
|
||||
|
||||
return base64Encode
|
||||
}
|
||||
|
||||
}
|
29
PSCBOnlineSample/Pods/PSCBOnline/PSCBOnline/Sources/Models/CustomerData.swift
generated
Normal file
29
PSCBOnlineSample/Pods/PSCBOnline/PSCBOnline/Sources/Models/CustomerData.swift
generated
Normal file
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// CustomerData.swift
|
||||
//
|
||||
//
|
||||
// Created by Antonov Ilia on 12.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// A costumer data to present in PaymentData
|
||||
public struct CustomerData: Codable {
|
||||
|
||||
/// Unique costumer ID
|
||||
let account: String
|
||||
|
||||
let comment: String?
|
||||
|
||||
let email: String?
|
||||
|
||||
let phone: String?
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case account = "customerAccount"
|
||||
case comment = "customerComment"
|
||||
case email = "customerEmail"
|
||||
case phone = "customerPhone"
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
//
|
||||
// Payment.swift
|
||||
//
|
||||
//
|
||||
// Created by AntonovIA on 12.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// MARK: - Payment methods
|
||||
|
||||
internal enum PaymentMethods: String {
|
||||
case shpa = "ac-shpa"
|
||||
}
|
||||
|
||||
// MARK: - Request Message
|
||||
|
||||
public struct Payment: Encodable {
|
||||
|
||||
// Required:
|
||||
|
||||
/// Payment amount in rub
|
||||
/// min: 1.00
|
||||
public let amount: Decimal
|
||||
|
||||
/// Your market order ID
|
||||
/// maxlength: 20
|
||||
public let orderId: String
|
||||
|
||||
// Payment method
|
||||
internal let paymentMethod: PaymentMethods = .shpa
|
||||
|
||||
// Optional:
|
||||
|
||||
/// Human readable `orderId`
|
||||
/// Defaults to `orderId`
|
||||
var showOrderId: String?
|
||||
|
||||
/// Detailed text describing this order payment.
|
||||
var details: String?
|
||||
|
||||
/// Data about paying customer
|
||||
var customer: CustomerData?
|
||||
|
||||
// <Not in use>
|
||||
var recurrentable: Bool = false
|
||||
|
||||
public init(amount: Decimal, orderId: String,
|
||||
showOrderId: String? = nil, details: String? = nil,
|
||||
customer: CustomerData? = nil, recurrentable: Bool = false) {
|
||||
self.amount = amount
|
||||
self.orderId = orderId
|
||||
self.showOrderId = (showOrderId == nil) ? orderId : showOrderId
|
||||
self.details = details
|
||||
self.customer = customer
|
||||
self.recurrentable = recurrentable
|
||||
}
|
||||
|
||||
// MARK: - Encoder
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case amount, orderId, showOrderId, details, recurrentable, customer
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(amount, forKey: .amount)
|
||||
try container.encode(orderId, forKey: .orderId)
|
||||
try container.encode(showOrderId, forKey: .showOrderId)
|
||||
try container.encode(details, forKey: .details)
|
||||
try container.encode(recurrentable, forKey: .recurrentable)
|
||||
|
||||
// Customer
|
||||
try customer?.encode(to: encoder)
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
|
||||
public static let example = Payment(
|
||||
amount: 150.00, orderId: String.random(length: 6),
|
||||
details: "Wonderful warm socks",
|
||||
customer: CustomerData(
|
||||
account: "ID-12345", comment: "By tomorrow please",
|
||||
email: "foo@bar.com", phone: "+7 900 000 00 00"
|
||||
)
|
||||
)
|
||||
|
||||
#endif
|
||||
|
||||
}
|
44
PSCBOnlineSample/Pods/PSCBOnline/PSCBOnline/Sources/Models/RequestWrapper.swift
generated
Normal file
44
PSCBOnlineSample/Pods/PSCBOnline/PSCBOnline/Sources/Models/RequestWrapper.swift
generated
Normal file
|
@ -0,0 +1,44 @@
|
|||
//
|
||||
// RequestWrapper.swift
|
||||
//
|
||||
//
|
||||
// Created by Antonov Ilia on 12.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// MARK: - Top level request
|
||||
|
||||
/// Top level request wrapper for OOS requests
|
||||
public struct RequestWrapper: Encodable {
|
||||
|
||||
/// Merchant ID
|
||||
public let marketPlaceId: String
|
||||
|
||||
/// Payment info
|
||||
public let payment: Payment
|
||||
|
||||
/// Encoded card data
|
||||
public let cardData: String
|
||||
|
||||
/// Creates instance of RequestWrapper
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - marketPlaceId: Your OOS market place ID
|
||||
/// - payment: Payment details object
|
||||
/// - cardData: Encoded card data
|
||||
///
|
||||
/// - Returns: Prepared request ready to fire
|
||||
public init(marketPlaceId: String, payment: Payment, cardData: String) {
|
||||
self.marketPlaceId = marketPlaceId
|
||||
self.payment = payment
|
||||
self.cardData = cardData
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case marketPlaceId = "marketPlace"
|
||||
case payment
|
||||
case cardData
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
//
|
||||
// Response.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by Antonov Ilia on 23.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// MARK: - PSCB OOS Response status
|
||||
public enum ResponseStatus: String, Decodable {
|
||||
case success = "STATUS_SUCCESS"
|
||||
case failure = "STATUS_FAILURE"
|
||||
}
|
||||
|
||||
// MARK: - Acquiring data
|
||||
public struct AcquiringResponseData: Decodable {
|
||||
public let paReq: String?
|
||||
public let order: String?
|
||||
public let termUrl: String?
|
||||
public let url: String?
|
||||
public let md: String?
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case order, termUrl = "TermUrl", url = "URL", md = "MD", paReq = "PaReq"
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - OOS Error
|
||||
|
||||
/// An error structure for OOS errors returned in flat JSON
|
||||
/// `errorCode` and `errorDescription`
|
||||
public struct ResponseError: Decodable {
|
||||
|
||||
public let code: String
|
||||
public let description: String?
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case code = "errorCode"
|
||||
case description = "errorDescription"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - OOS Response
|
||||
|
||||
/// JSON Response from OOS API
|
||||
public struct Response: Decodable {
|
||||
|
||||
public let status: ResponseStatus
|
||||
public let requestId: String
|
||||
public let error: ResponseError?
|
||||
public let payment: ResponsePayment?
|
||||
public let acquiringData: AcquiringResponseData?
|
||||
public let description: String?
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case status, requestId, payment, acquiringData, description
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
self.status = try container.decode(ResponseStatus.self, forKey: .status)
|
||||
self.requestId = try container.decode(String.self, forKey: .requestId)
|
||||
self.description = try? container.decode(String.self, forKey: .description)
|
||||
|
||||
// Decode flat and nested data into nested structs
|
||||
self.payment = try? container.decode(ResponsePayment.self, forKey: .payment)
|
||||
self.acquiringData = try? AcquiringResponseData(from: decoder)
|
||||
self.error = try? ResponseError(from: decoder)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Payment status
|
||||
/// Payment stats
|
||||
/// see: https://docs.pscb.ru/oos/index.html#obshaya-informaciya-spravochniki-statusy-platezhej
|
||||
public enum PaymentState: String, Decodable {
|
||||
case sent = "sent"
|
||||
case new = "new"
|
||||
case end = "end"
|
||||
case refunded = "ref"
|
||||
case hold = "hold"
|
||||
case expired = "exp"
|
||||
case canceled = "canceled"
|
||||
case error = "error"
|
||||
case rejected = "rej"
|
||||
case undefined = "undef"
|
||||
}
|
||||
|
||||
// MARK: - Payment response struct
|
||||
public struct ResponsePayment: Decodable {
|
||||
public let orderId: String
|
||||
public let showOrderId: String
|
||||
public let paymentId: String
|
||||
public let amount: Decimal
|
||||
public let state: PaymentState
|
||||
public let marketPlace: UInt16
|
||||
public let stateDate: Date
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
//
|
||||
// OOSAPI.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by Antonov Ilia on 27.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import PassKit
|
||||
|
||||
/// Utility fabric methods required for PSCB API.
|
||||
public class PSCBAPI {
|
||||
|
||||
public static let supportedNetworks: [PKPaymentNetwork] = [.visa, .masterCard]
|
||||
|
||||
/// - Returns: a tuple describing if application `canMakePayments` and `canSetupCards` using supported networks.
|
||||
public class func canMakePayments() -> (canMakePayments: Bool, canSetupCards: Bool) {
|
||||
return (
|
||||
PKPaymentAuthorizationController.canMakePayments(),
|
||||
PKPaymentAuthorizationController.canMakePayments(usingNetworks: supportedNetworks)
|
||||
)
|
||||
}
|
||||
|
||||
/// Creates a default instance of `PKPaymentRequest` with pre-default parameters.
|
||||
///
|
||||
/// - Returns: `PKPaymentRequest`
|
||||
public class func makePaymentRequest(items: [PKPaymentSummaryItem]) -> PKPaymentRequest {
|
||||
return makePaymentRequest(merchantId: "merchant.pscb.pay", items: items)
|
||||
}
|
||||
|
||||
/// Creates a default instance of `PKPaymentRequest` with pre-default parameters.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - merchantId: Your Apple Pay merchant ID
|
||||
/// - items: Summary items
|
||||
///
|
||||
/// - Returns: `PKPaymentRequest`
|
||||
public class func makePaymentRequest(merchantId: String, items: [PKPaymentSummaryItem]) -> PKPaymentRequest {
|
||||
let request = PKPaymentRequest()
|
||||
request.merchantIdentifier = merchantId
|
||||
request.supportedNetworks = Self.supportedNetworks
|
||||
|
||||
if #available(iOS 11.0, *) {
|
||||
//request.supportedCountries = ["RU", "UA", "BY", "US"]
|
||||
}
|
||||
|
||||
request.merchantCapabilities = .capability3DS
|
||||
request.countryCode = "RU"
|
||||
request.currencyCode = "RUB"
|
||||
request.paymentSummaryItems = items
|
||||
|
||||
return request
|
||||
}
|
||||
|
||||
}
|
306
PSCBOnlineSample/Pods/PSCBOnline/PSCBOnline/Sources/PSCBOnlineClient.swift
generated
Normal file
306
PSCBOnlineSample/Pods/PSCBOnline/PSCBOnline/Sources/PSCBOnlineClient.swift
generated
Normal file
|
@ -0,0 +1,306 @@
|
|||
//
|
||||
// OOSAPIClient.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by Antonov Ilia on 12.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import PassKit
|
||||
|
||||
// MARK: - Environments
|
||||
|
||||
public enum BackendEnvironment: String {
|
||||
|
||||
case production = "oos.pscb.ru"
|
||||
case sandbox = "oosdemo.pscb.ru"
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Request status
|
||||
|
||||
/// Backend request status
|
||||
/// Consists of two possible states: `.success` and `.failure`.
|
||||
///
|
||||
/// This one represents if request to the backend server was successful
|
||||
public enum RequestStatus {
|
||||
case success, failure
|
||||
}
|
||||
|
||||
// MARK: - Response wrapper
|
||||
|
||||
/// Backend response
|
||||
public struct BackendResponse {
|
||||
|
||||
/// Represents request status
|
||||
public let status: RequestStatus
|
||||
|
||||
/// Hold error information if request is a `.failure`
|
||||
public let error: Error?
|
||||
|
||||
/// Holds response information if request is a `.success`
|
||||
public let response: Response?
|
||||
}
|
||||
|
||||
// MARK: - Alias for completion handler
|
||||
|
||||
/// Callback for `OOSAPIClient.send` method
|
||||
public typealias APICompletionHandler = (BackendResponse) -> Void
|
||||
|
||||
/// Callback for another `OOSAPIClient.send` method which fires after certain guards ensure success or failure
|
||||
/// to simplify API usage
|
||||
public typealias PostResponseHandler = (Error?, Response?) -> Void
|
||||
|
||||
// MARK: - API Integration errors
|
||||
|
||||
/// Possible erros when dealing with OOS backend
|
||||
public enum OOSErrors: Error {
|
||||
case noData
|
||||
case parse(Error)
|
||||
case cause(Error)
|
||||
|
||||
/// Consists of error code and error description
|
||||
case backend(String, String)
|
||||
}
|
||||
|
||||
// MARK: - API Client
|
||||
|
||||
/// Implementation of OOS Merchant API HTTP protocol.
|
||||
final public class PSCBOnlineClient {
|
||||
|
||||
private lazy var urlSession: URLSession = {
|
||||
URLSession(configuration: .default, delegate: nil, delegateQueue: .main)
|
||||
}()
|
||||
|
||||
private lazy var url: URL = {
|
||||
var components = URLComponents()
|
||||
components.scheme = "https"
|
||||
components.host = self.environment.rawValue
|
||||
components.path = "/merchantApi/payShpa"
|
||||
|
||||
return components.url!
|
||||
}()
|
||||
|
||||
private let decoder = JSONDecoders.iso8601DateAwareDecoder()
|
||||
|
||||
// init:
|
||||
|
||||
let environment: BackendEnvironment
|
||||
let marketPlaceId: String
|
||||
let signingKey: String
|
||||
|
||||
/// Initializes `OOSAPIClient`
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - environment: Backend environment. Which one to use. For testing environment use `.sandbox`
|
||||
/// - marketPlaceId: Your OOS market-place ID
|
||||
/// - siginingKey: Your OOS signing key
|
||||
public init(environment: BackendEnvironment, marketPlaceId: String, signingKey: String) {
|
||||
self.environment = environment
|
||||
self.marketPlaceId = marketPlaceId
|
||||
self.signingKey = signingKey
|
||||
}
|
||||
|
||||
// impl:
|
||||
|
||||
/// Creates instance of `RequestWrapper` for a backend to process from given PKPayment instance and other details
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - payment: authorized PKPayment instance
|
||||
/// - amount: total order amount
|
||||
/// - orderId: Unique merchant order ID
|
||||
///
|
||||
/// - Returns: RequestWrapper instance for backend
|
||||
public func makeRequestWithPayment(payment: PKPayment, amount: Decimal, orderId: String) throws -> RequestWrapper {
|
||||
return try makeRequestWithPayment(pkPayment: payment, payment: Payment(amount: amount, orderId: orderId))
|
||||
}
|
||||
|
||||
/// Creates instance of `RequestWrapper` for a backend to process from given `PKPayment` instance and backend `Payment` instance
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - pkPayment: authorized `PKPayment` instance
|
||||
/// - payment: backend `Payment` details
|
||||
///
|
||||
/// - Returns: RequestWrapper instance for backend
|
||||
public func makeRequestWithPayment(pkPayment: PKPayment, payment: Payment) throws -> RequestWrapper {
|
||||
// Get card data cryptogram from payment token
|
||||
let cardDataCrypto = try pkPayment.token.toCryptogramString()
|
||||
|
||||
// Backend request wrapper
|
||||
let requestWrapper = RequestWrapper(
|
||||
marketPlaceId: self.marketPlaceId,
|
||||
payment: payment,
|
||||
cardData: cardDataCrypto
|
||||
)
|
||||
|
||||
// Fail early
|
||||
try requestWrapper.assumeSerializes()
|
||||
|
||||
return requestWrapper
|
||||
}
|
||||
|
||||
/// Creates instance of `RequestWrapper` for a backend to process from raw card data instead of ApplePay token
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// let card = CardData(
|
||||
/// pan: "409444400001234",
|
||||
/// expiryYear: 2025,
|
||||
/// expiryMonth: 12,
|
||||
/// cvCode: "000",
|
||||
/// cardholder: "JOHN DOE"
|
||||
/// )
|
||||
///
|
||||
/// let payment = Payment(amount: Decimal(1500), orderId: "XC-12345")
|
||||
/// let request = try apiClient.createRequestWithCardData(card: card, payment: payment)
|
||||
///
|
||||
/// // Send to backend:
|
||||
/// apiClient.send(request) { (response) in /code/ }
|
||||
/// ```
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - cardData: an instance of card data.
|
||||
public func makeRequestWithCardData(card: CardData, payment: Payment) throws -> RequestWrapper {
|
||||
let cryptogram = try card.toCryptgramString()
|
||||
let request = RequestWrapper(
|
||||
marketPlaceId: self.marketPlaceId,
|
||||
payment: payment,
|
||||
cardData: cryptogram
|
||||
)
|
||||
|
||||
// Fail-early compile
|
||||
try request.assumeSerializes()
|
||||
|
||||
return request
|
||||
}
|
||||
|
||||
/// Signs and sends compiled `RequestWrapper` to the backend server
|
||||
/// Fires `APICompletionHandler` once requests succeeds or fails
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - request: `RequestWrapper` created from `createRequestWithPayment(...)`
|
||||
/// - completionHander: `APICompletionHandler` a callback for when requests succeeds or fails
|
||||
///
|
||||
public func send(_ request: RequestWrapper, completionHandler: @escaping APICompletionHandler) {
|
||||
// Calculate signature and get HTTP body at the same time
|
||||
let httpBody = try! request.serializeToString()
|
||||
let signature = calculateSignature(httpBody)
|
||||
|
||||
// Request params
|
||||
let url = self.url
|
||||
var req = URLRequest(url: url)
|
||||
|
||||
// Set request parameters
|
||||
req.httpMethod = "POST"
|
||||
req.httpBody = httpBody.data(using: .utf8)
|
||||
req.setValue(signature, forHTTPHeaderField: "Signature")
|
||||
|
||||
print(">> Request JSON: \(String(describing: String(data: req.httpBody!, encoding: .utf8)))")
|
||||
|
||||
let task = urlSession.dataTask(with: req) { (data, res, err) in
|
||||
guard err == nil else {
|
||||
let error = self.err_requestError(req, error: err)
|
||||
completionHandler(error)
|
||||
return
|
||||
}
|
||||
|
||||
guard let data = data else {
|
||||
let error = self.failure(req, error: OOSErrors.noData)
|
||||
completionHandler(error)
|
||||
return
|
||||
}
|
||||
|
||||
print("<< Response data: \(String(data: data, encoding: .utf8) ?? "N/A")")
|
||||
|
||||
do {
|
||||
let response = try self.decoder.decode(Response.self, from: data)
|
||||
|
||||
// Finaly success
|
||||
let success = BackendResponse(status: .success, error: nil, response: response)
|
||||
|
||||
completionHandler(success)
|
||||
} catch let error {
|
||||
print("Failed to do task on request \(req)")
|
||||
print(error.localizedDescription)
|
||||
|
||||
// Reading and parsing errors
|
||||
let failure = self.failure(req, error: .parse(error))
|
||||
completionHandler(failure)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Fire task
|
||||
task.resume()
|
||||
}
|
||||
|
||||
/// Signs and sends compiled `RequestWrapper` to the backend server
|
||||
/// Fires `PostResponseHandler` once requests succeeds or fails.
|
||||
/// `PostResponseHandler` accepts two arguments: `Error?` and `Response?`.
|
||||
///
|
||||
/// If requests succeeds and payment in desired state `Error?` will always be `nil`.
|
||||
/// `Response?` presents on some errors and on all successes.
|
||||
///
|
||||
/// This is an utility method to reduce boilerplate for necessary checks.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - request: `RequestWrapper` created from `createRequestWithPayment(...)`
|
||||
/// - completionHander: `APICompletionHandler` a callback for when requests succeeds or fails
|
||||
///
|
||||
public func send(_ request: RequestWrapper, responseHandler: @escaping PostResponseHandler) {
|
||||
// Construct a closure wrapper with predefined guards and checks
|
||||
let wrapper: APICompletionHandler = { (backendResponse) in
|
||||
// HTTP request succeeded?
|
||||
guard backendResponse.status == .success else {
|
||||
print("Failed to execute request due to error: \(String(describing: backendResponse.error))")
|
||||
|
||||
responseHandler(OOSErrors.cause(backendResponse.error!), nil)
|
||||
return
|
||||
}
|
||||
|
||||
// Backend returned valid response?
|
||||
guard let response = backendResponse.response else {
|
||||
print("Backend returned empty body")
|
||||
|
||||
responseHandler(OOSErrors.noData, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// Backend payment succeeded?
|
||||
guard response.status == .success else {
|
||||
print("Unable to process payment")
|
||||
|
||||
let responseError = response.error
|
||||
let backendError = OOSErrors.backend(responseError?.code ?? "FAILED", responseError?.description ?? "")
|
||||
|
||||
// At this point we can pass response too
|
||||
responseHandler(backendError, response)
|
||||
return
|
||||
}
|
||||
|
||||
// Finally succeeds
|
||||
responseHandler(nil, response)
|
||||
}
|
||||
|
||||
// Send using more lower-level method above
|
||||
send(request, completionHandler: wrapper)
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func err_requestError(_ req: URLRequest, error: Error?) -> BackendResponse {
|
||||
print("Failed to do task on request \(req) with error: \(String(describing: error))")
|
||||
return BackendResponse(status: .failure, error: OOSErrors.cause(error!), response: nil)
|
||||
}
|
||||
|
||||
private func failure(_ req: URLRequest, error: OOSErrors) -> BackendResponse {
|
||||
print("Request \(req) failed with error: \(String(describing: error))")
|
||||
return BackendResponse(status: .failure, error: error, response: nil)
|
||||
}
|
||||
|
||||
private func calculateSignature(_ jsonString: String) -> String {
|
||||
let composite = (jsonString + self.signingKey)
|
||||
return DigestHelper.sha256String(composite)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
//
|
||||
// PaymentHandler.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by Antonov Ilia on 16.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import PassKit
|
||||
|
||||
public typealias PaymentCompletionHandler = (Bool) -> Void
|
||||
|
||||
public class ApplePayHandler: NSObject {
|
||||
|
||||
static let supportedNetworks: [PKPaymentNetwork] = [.visa, .masterCard]
|
||||
|
||||
// MARK: - Fields
|
||||
|
||||
public let merchantId: String
|
||||
public let merchantKey: String
|
||||
public let summaryItems: [PKPaymentSummaryItem]
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
var paymentController: PKPaymentAuthorizationController?
|
||||
var paymentStatus: PKPaymentAuthorizationStatus = .failure
|
||||
var completionHandler: PaymentCompletionHandler?
|
||||
var payment: Payment?
|
||||
|
||||
public init?(merchantId: String, merchantKey: String, summaryItems: [PKPaymentSummaryItem]) {
|
||||
guard PKPaymentAuthorizationController.canMakePayments(usingNetworks: Self.supportedNetworks) else {
|
||||
print("Could not instantiate ApplePayHandler. Cannot make payments with provided networks")
|
||||
return nil
|
||||
}
|
||||
|
||||
self.merchantId = merchantId
|
||||
self.merchantKey = merchantKey
|
||||
self.summaryItems = summaryItems
|
||||
}
|
||||
|
||||
public func handle(payment: Payment, completion: @escaping PaymentCompletionHandler) {
|
||||
self.completionHandler = completion
|
||||
self.payment = payment
|
||||
|
||||
NSLog("About to handle payment: \(payment)")
|
||||
|
||||
paymentController = PKPaymentAuthorizationController(paymentRequest: paymentRequest)
|
||||
paymentController?.delegate = self
|
||||
paymentController?.present { (presented) in
|
||||
if !presented {
|
||||
NSLog("Could not present PKPaymentAuthorizationController")
|
||||
self.completionHandler!(false)
|
||||
} else {
|
||||
NSLog("PKPaymentAuthorizationController presented")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Private details
|
||||
|
||||
private var paymentRequest: PKPaymentRequest {
|
||||
let request = PKPaymentRequest()
|
||||
|
||||
request.countryCode = "RU"
|
||||
request.merchantIdentifier = "merchant.pscb.pay"
|
||||
request.currencyCode = "RUB"
|
||||
request.supportedNetworks = Self.supportedNetworks
|
||||
request.merchantCapabilities = .capability3DS
|
||||
request.paymentSummaryItems = summaryItems
|
||||
|
||||
return request
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Extension for PKPaymentAuthorizationControllerDelegate
|
||||
|
||||
extension ApplePayHandler: PKPaymentAuthorizationControllerDelegate {
|
||||
|
||||
public func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController,
|
||||
didAuthorizePayment payment: PKPayment,
|
||||
completion: @escaping (PKPaymentAuthorizationStatus) -> Void) {
|
||||
|
||||
// print("Payment string")
|
||||
// let paymentString = try! payment.serializeToString()
|
||||
// print(paymentString)
|
||||
//
|
||||
// //
|
||||
//
|
||||
// self.paymentStatus = .success
|
||||
completion(PKPaymentAuthorizationStatus.success)
|
||||
}
|
||||
|
||||
@available(iOS 11.0, *)
|
||||
public func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController, didAuthorizePayment payment: PKPayment, handler completion: @escaping (PKPaymentAuthorizationResult) -> Void) {
|
||||
//
|
||||
// NSLog("About to send request to backend")
|
||||
// let paymentString = try! payment.serializeToString()
|
||||
//
|
||||
// NSLog("Payment JSON: \(paymentString)")
|
||||
//
|
||||
let result = PKPaymentAuthorizationResult(status: .success, errors: nil)
|
||||
completion(result)
|
||||
self.completionHandler?(true)
|
||||
}
|
||||
|
||||
public func paymentAuthorizationControllerDidFinish(_ controller: PKPaymentAuthorizationController) {
|
||||
controller.dismiss(completion: nil)
|
||||
}
|
||||
|
||||
}
|
79
PSCBOnlineSample/Pods/PSCBOnline/PSCBOnline/Sources/Serializable/PKPaymentToken+Serializable.swift
generated
Normal file
79
PSCBOnlineSample/Pods/PSCBOnline/PSCBOnline/Sources/Serializable/PKPaymentToken+Serializable.swift
generated
Normal file
|
@ -0,0 +1,79 @@
|
|||
//
|
||||
// PKPaymentToken+Serializable.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by OA on 17.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import PassKit
|
||||
|
||||
// MARK: - Comfront to serializable
|
||||
extension PKPaymentToken: Serializable {
|
||||
|
||||
// Serializes token to a JSONLike dictionary
|
||||
public func serializeToJSON() -> JSONDict {
|
||||
let paymentJson: JSONDict? = try? JSONSerialization.jsonObject(
|
||||
with: self.paymentData, options: .mutableContainers
|
||||
) as? JSONDict
|
||||
|
||||
var paymentType: String = "debit"
|
||||
var methodAndNetwork: JSONDict = [
|
||||
"network": "",
|
||||
"type": paymentType,
|
||||
"displayName": ""
|
||||
]
|
||||
|
||||
if #available(iOS 9.0, *) {
|
||||
methodAndNetwork = [
|
||||
"network": self.paymentMethod.network?.rawValue ?? "",
|
||||
"type": paymentType,
|
||||
"displayName": self.paymentMethod.displayName ?? ""
|
||||
]
|
||||
|
||||
switch self.paymentMethod.type {
|
||||
case .debit:
|
||||
paymentType = "debit"
|
||||
case .credit:
|
||||
paymentType = "credit"
|
||||
case .store:
|
||||
paymentType = "store"
|
||||
case .prepaid:
|
||||
paymentType = "prepaid"
|
||||
default:
|
||||
paymentType = "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
"paymentData": paymentJson,
|
||||
"transactionIdentifier": self.transactionIdentifier,
|
||||
"paymentMethod": methodAndNetwork
|
||||
] as JSONDict
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - To string cryptogram
|
||||
extension PKPaymentToken {
|
||||
|
||||
private func paymentJSONData() -> JSONDict? {
|
||||
let json = self.serializeToJSON()
|
||||
let data = json["paymentData"] as! JSONDict?
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
/// Creates a Base64 encoded cryptogram string accepted by PSCB OOS protocol
|
||||
/// May throw JSON serialization errors if token could not be converted to JSON string before writing a cryptogram.
|
||||
///
|
||||
/// - Returns: Base64 encoded string
|
||||
public func toCryptogramString() throws -> String {
|
||||
let json = self.paymentJSONData()
|
||||
let data = try JSONSerialization.data(withJSONObject: json!, options: [])
|
||||
// let string = String(data: data, encoding: .utf8)!
|
||||
|
||||
return data.base64EncodedString(options: Data.Base64EncodingOptions(rawValue: 0))
|
||||
}
|
||||
|
||||
}
|
27
PSCBOnlineSample/Pods/PSCBOnline/PSCBOnline/Sources/Serializable/Payment+Serializable.swift
generated
Normal file
27
PSCBOnlineSample/Pods/PSCBOnline/PSCBOnline/Sources/Serializable/Payment+Serializable.swift
generated
Normal file
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// Payment+Serializable.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by Antonov Ilia on 21.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Payment: Serializable {
|
||||
|
||||
public func serializeToJSON() -> JSONDict {
|
||||
var json = JSONDict()
|
||||
json["orderId"] = self.orderId
|
||||
json["amount"] = self.amount
|
||||
json["showOrderId"] = self.showOrderId
|
||||
json["details"] = self.details
|
||||
json["recurrentable"] = self.recurrentable
|
||||
json["customerAccount"] = self.customer?.account
|
||||
json["customerComment"] = self.customer?.comment
|
||||
json["customerEmail"] = self.customer?.email
|
||||
json["customerPhone"] = self.customer?.phone
|
||||
|
||||
return json
|
||||
}
|
||||
|
||||
}
|
21
PSCBOnlineSample/Pods/PSCBOnline/PSCBOnline/Sources/Serializable/RequestWrapper+Serializable.swift
generated
Normal file
21
PSCBOnlineSample/Pods/PSCBOnline/PSCBOnline/Sources/Serializable/RequestWrapper+Serializable.swift
generated
Normal file
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// RequestWrapper+Serializable.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by Antonov Ilia on 18.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension RequestWrapper: Serializable {
|
||||
|
||||
public func serializeToJSON() -> JSONDict {
|
||||
var json = JSONDict()
|
||||
json["marketPlace"] = self.marketPlaceId
|
||||
json["payment"] = self.payment.serializeToJSON()
|
||||
json["cardData"] = self.cardData
|
||||
|
||||
return json
|
||||
}
|
||||
|
||||
}
|
61
PSCBOnlineSample/Pods/PSCBOnline/PSCBOnline/Sources/Serializable/Serializable.swift
generated
Normal file
61
PSCBOnlineSample/Pods/PSCBOnline/PSCBOnline/Sources/Serializable/Serializable.swift
generated
Normal file
|
@ -0,0 +1,61 @@
|
|||
//
|
||||
// Serializable.swift
|
||||
// PSCB-OOS-iOS
|
||||
//
|
||||
// Created by OA on 16.10.2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// MARK: - Serializable
|
||||
|
||||
public protocol Serializable {
|
||||
|
||||
/// Serializes current object to generic JSON-Like dictionary
|
||||
func serializeToJSON() -> JSONDict
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Extension
|
||||
|
||||
public extension Serializable {
|
||||
|
||||
/// Serializes current object to data
|
||||
func serializeToData() throws -> Data {
|
||||
// let encoder = JSONEncoder()
|
||||
// let data = try encoder.encode(self.serializeToJSON())
|
||||
//
|
||||
// return data
|
||||
return try JSONSerialization.data(
|
||||
withJSONObject: self.serializeToJSON(),
|
||||
options: []
|
||||
)
|
||||
}
|
||||
|
||||
/// Serialzes to JSON-String
|
||||
func serializeToString() throws -> String {
|
||||
let data = try self.serializeToData()
|
||||
return String(data: data, encoding: .utf8)!
|
||||
}
|
||||
|
||||
/// Used for checking purposes if this object can be serialized without exception
|
||||
func assumeSerializes() throws {
|
||||
try serializeToString()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - JSONDict
|
||||
|
||||
public typealias JSONDict = [AnyHashable: AnyHashable]
|
||||
|
||||
//extension JSONDict {
|
||||
//
|
||||
// public mutating func add<T: RawRepresentable>(key: T, nullable value: JSONDict.Value?) where T.RawValue == JSONDict.Key {
|
||||
// if let value = value {
|
||||
// self.updateValue(value, forKey: key.rawValue)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
# ПСКБ Платежи iOS SDK
|
||||
|
||||
[![Platform](https://img.shields.io/badge/Support-iOS%2010.0+-brightgreen.svg)](https://img.shields.io/badge/Support-iOS%2010.3+-brightgreen.svg)
|
||||
|
||||
Библиотека является дополнением к API системы интернет-эквайринга [ПСКБ "Платежи"](https://online.pscb.ru)
|
||||
и позволяет подключить приём платежей по картам в мобильных приложениях iOS с минимальными усилиями.
|
||||
|
||||
## Возможности
|
||||
|
||||
На текущий момент библиотека поддерживает:
|
||||
|
||||
- Apple Pay
|
||||
- Оплата картами
|
||||
|
||||
## Подключение зависимостей
|
||||
|
||||
1. Установите CocoaPods 1.10.0 или выше
|
||||
|
||||
```zsh
|
||||
gem install cocoapods
|
||||
```
|
||||
[Официальная документация по установке CocoaPods](https://guides.cocoapods.org/using/getting-started.html)
|
||||
|
||||
2. Создайте в своём приложении `Podfile`
|
||||
|
||||
Это также можно сделать при помощи команды `pod init` , находясь в директории своего проекта. (В таком случае будет создан `Podfile` с настройками по умолчанию)
|
||||
|
||||
3. Добавьте зависимости в `Podfile`
|
||||
|
||||
```ruby
|
||||
platform :ios, '10.0'
|
||||
|
||||
target '<Target name>' do
|
||||
use_frameworks!
|
||||
|
||||
pod 'PSCBOnline', :git => "https://bitbucket.org/dev_ai/pscbonline.git", :tag => "1.0.0"
|
||||
|
||||
end
|
||||
```
|
||||
|
||||
> `<Target name>` - Название проекта вашего приложения в XCode
|
||||
|
||||
4. Выполните команду `pod install`
|
||||
|
||||
## Интеграция
|
||||
|
||||
1. Для работы с библиотекой импортируйте зависимости в нужный файл проекта:
|
||||
|
||||
```swift
|
||||
import PSCBOnline
|
||||
```
|
||||
|
||||
2. Создайте экземпляр `PSCBOnlineClient` с вашими настройками:
|
||||
|
||||
```swift
|
||||
let apiClient = PSCBOnlineClient(
|
||||
environment: .sandbox,
|
||||
marketPlaceId: "<Your MarketPlace ID>",
|
||||
signingKey: "<Your Signing Key>"
|
||||
)
|
||||
```
|
||||
|
||||
> `environment` - окружение, в рамках которого библиотека взаимодействует с сервисом. `.sandbox` - тестовое окружение; `.production` - продуктовое.
|
||||
> `Your MarketPlace ID` - ваш идентификатор в системе ПСКБ-Онлайн.
|
||||
> `Your Signing Key` - ваш ключ подписи запросов к системе.
|
||||
|
||||
3. Создайте экземпляр `Payment`
|
||||
|
||||
```swift
|
||||
let payment = Payment(amount: Decimal(1000.00), orderId: "Order-ID")
|
||||
```
|
||||
> `amount` - сумма в рублях. (_На текущий момент другая валюта не поддерживается._)
|
||||
> `orderId` - уникальный идентификатор заказа в рамках магазина.
|
||||
|
||||
_Для детальной информации, какие параметры принимает смотрите документацию `Payment`._
|
||||
|
||||
----
|
||||
|
||||
Дальнейшая интеграция отличается от способа оплаты.
|
||||
|
||||
## Доступные способы оплаты
|
||||
|
||||
Сейчас в SDK доступна оплата:
|
||||
|
||||
- Банковкой кратой
|
||||
- Apple Pay
|
||||
|
||||
Для их настройки реализации смотрите дальше.
|
||||
|
||||
### Приём оплаты банковскимикартами
|
||||
|
||||
1. Для приёма оплаты картами нужно создать экземпляр класса `CardData`.
|
||||
|
||||
```swift
|
||||
let card = CardData(
|
||||
pan: "4761349750010326",
|
||||
expiryYear: 2022,
|
||||
expiryMonth: 12,
|
||||
cvCode: "851"
|
||||
)
|
||||
```
|
||||
|
||||
2. Создать токен запроса, используя экземпляр `PSCBOnlineClient`, созданный ранее.
|
||||
|
||||
```swift
|
||||
let request = try! client.makeRequestWithCardData(card: card, payment: payment)
|
||||
```
|
||||
|
||||
3. Отправить токен запроса на сервер ПСКБ-Онлайн.
|
||||
|
||||
```swift
|
||||
// Send request to backend
|
||||
client.send(request, responseHandler: { (error, response) in
|
||||
guard nil == error && nil != response else {
|
||||
print("Error sending request: \(String(describing: error))")
|
||||
return
|
||||
}
|
||||
|
||||
print("Successful request:")
|
||||
print(response!)
|
||||
})
|
||||
```
|
||||
|
||||
> В случае успешного выполнения запроса, `response` будет содержать информацию о принятом платеже, его ID, состояние и прочие данные.
|
||||
|
||||
### Приём оплаты Apple Pay
|
||||
|
||||
Для приёма платежей через Apple Pay вы должны зарегестрировать Merchant ID в Apple.
|
||||
|
||||
Помимо `merchant ID` необходимо настроить сертификат обработки запросов (`Payment Processing Certificate`) и передать его ПСКБ-Онлайн. Этим сертификатом Apple будет шифровать данные банковских карт перед отправкой на сервер ПСКБ-Онлайн.
|
||||
|
||||
Все пререквизиты описаны на сайте [официальной документации Apple](https://developer.apple.com/documentation/passkit/apple_pay/setting_up_apple_pay_requirements).
|
||||
|
||||
Также вы можете ознакомиться сподробной инструкцией на сайте документации [ПСКБ Онлайн](https://docs.pscb.ru/oos/advanced.html#dopolnitelnye-opcii-apple-pay).
|
||||
|
||||
---
|
||||
|
||||
После выполнения пререквизитов, в коде необходимо:
|
||||
|
||||
1. Импортировать `PassKit`:
|
||||
|
||||
```swift
|
||||
import PassKit
|
||||
```
|
||||
|
||||
2. Создать экземпляр класса `PKPaymentAuthorizationController` и настроить делегирующий класс `PKPaymentAuthorizationControllerDelegate`:
|
||||
|
||||
Пример:
|
||||
|
||||
```swift
|
||||
import PassKit
|
||||
import PSCBOnline
|
||||
|
||||
class ApplePayHandler: NSObject {
|
||||
|
||||
public func handleApplePay(payment: Payment) {
|
||||
// Позиции оплаты для представления пользователя
|
||||
let items = [PKPaymentSummaryItem(label: "Shoes", amount: NSDecimalNumber(intergerLiteral: 1000))]
|
||||
|
||||
// Запрос на оплату для PKPaymentAuthorizationController
|
||||
let paymentRequest = PSCBAPI.makePaymentRequest(merchantId: "<Your Apple Merchant ID>", items: [])
|
||||
|
||||
// Вызов модуля оплаты
|
||||
let authorizationController = PKPaymentAuthorizationController(paymentRequest: paymentRequest)
|
||||
|
||||
authorizationController?.delegate = self
|
||||
authorizationController?.present(completion: { presented in
|
||||
if presented {
|
||||
print("Controller presented")
|
||||
} else {
|
||||
print("Controller could not be presented")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
extension ApplePayHandler: PKPaymentAuthorizationControllerDelegate {
|
||||
|
||||
public func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController,
|
||||
didAuthorizePayment payment: PKPayment,
|
||||
handler completion: @escaping (PKPaymentAuthorizationResult) -> Void) {
|
||||
|
||||
// 1.
|
||||
// Вызывается после авторизации платежа плательщиком биометрическими данными или паролем
|
||||
}
|
||||
|
||||
public func paymentAuthorizationControllerDidFinish(_ controller: PKPaymentAuthorizationController) {
|
||||
// 2.
|
||||
// Вызывается после того, как платёж совершён или пользователь закрыл модуль оплаты.
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
> `<Your Apple Merchant ID>` - Ваш идентификатор мерчанта.
|
||||
|
||||
3. Далее в примере выше в п.1 и п.2 реализовать необходимую логику отправки запроса на сервер ПСКБ-Онлайн.
|
||||
Для пункта 1 - это создание токена запроса (используя `client.makeRequestWithPayment(pkPayment, pscbPayment)` и отправка его на сервер:
|
||||
|
||||
```swift
|
||||
// Request token
|
||||
let request = try! client.makeRequestWithPayment(pkPayment: pkPayment, pscbPayment: payment)
|
||||
|
||||
// Sending request to backend
|
||||
client.send(request, responseHandler: { (error, response) in
|
||||
if (error == nil && response != nil) {
|
||||
completion(PKPaymentAuthorizationResult(status: .success, errors: nil))
|
||||
} else {
|
||||
print("Error sending payment: \(String(describing: error))")
|
||||
completion(PKPaymentAuthorizationResult(status: .failure, errors: nil))
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
4. А для пункта 2 - обработка закрытия модуля оплаты.
|
||||
|
||||
## Описание классов и параметров
|
File diff suppressed because it is too large
Load Diff
60
PSCBOnlineSample/Pods/Pods.xcodeproj/xcuserdata/oa.xcuserdatad/xcschemes/PSCBOnline.xcscheme
generated
Normal file
60
PSCBOnlineSample/Pods/Pods.xcodeproj/xcuserdata/oa.xcuserdatad/xcschemes/PSCBOnline.xcscheme
generated
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1100"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForAnalyzing = "YES"
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "DEF6F46953D81544729456672DEB8C3B"
|
||||
BuildableName = "PSCBOnline.framework"
|
||||
BlueprintName = "PSCBOnline"
|
||||
ReferencedContainer = "container:Pods.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
buildConfiguration = "Debug"
|
||||
allowLocationSimulation = "YES">
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -0,0 +1,58 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1100"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "3E950DEFA4527CA727310C9636D007AA"
|
||||
BuildableName = "Pods_PSCBOnlineSample_PSCBOnlineSampleUITests.framework"
|
||||
BlueprintName = "Pods-PSCBOnlineSample-PSCBOnlineSampleUITests"
|
||||
ReferencedContainer = "container:Pods.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -0,0 +1,58 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1100"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "E2DB125EC4D0570EFCBF775B921460CD"
|
||||
BuildableName = "Pods_PSCBOnlineSample.framework"
|
||||
BlueprintName = "Pods-PSCBOnlineSample"
|
||||
ReferencedContainer = "container:Pods.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -0,0 +1,58 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1100"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "BFE11DEFCEE6C73419C9155DCB4FE27B"
|
||||
BuildableName = "Pods_PSCBOnlineSampleTests.framework"
|
||||
BlueprintName = "Pods-PSCBOnlineSampleTests"
|
||||
ReferencedContainer = "container:Pods.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
31
PSCBOnlineSample/Pods/Pods.xcodeproj/xcuserdata/oa.xcuserdatad/xcschemes/xcschememanagement.plist
generated
Normal file
31
PSCBOnlineSample/Pods/Pods.xcodeproj/xcuserdata/oa.xcuserdatad/xcschemes/xcschememanagement.plist
generated
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>PSCBOnline.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<key>Pods-PSCBOnlineSample-PSCBOnlineSampleUITests.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<key>Pods-PSCBOnlineSample.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<key>Pods-PSCBOnlineSampleTests.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict/>
|
||||
</dict>
|
||||
</plist>
|
26
PSCBOnlineSample/Pods/Target Support Files/PSCBOnline/PSCBOnline-Info.plist
generated
Normal file
26
PSCBOnlineSample/Pods/Target Support Files/PSCBOnline/PSCBOnline-Info.plist
generated
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?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>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${CURRENT_PROJECT_VERSION}</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,5 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
@interface PodsDummy_PSCBOnline : NSObject
|
||||
@end
|
||||
@implementation PodsDummy_PSCBOnline
|
||||
@end
|
12
PSCBOnlineSample/Pods/Target Support Files/PSCBOnline/PSCBOnline-prefix.pch
generated
Normal file
12
PSCBOnlineSample/Pods/Target Support Files/PSCBOnline/PSCBOnline-prefix.pch
generated
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifdef __OBJC__
|
||||
#import <UIKit/UIKit.h>
|
||||
#else
|
||||
#ifndef FOUNDATION_EXPORT
|
||||
#if defined(__cplusplus)
|
||||
#define FOUNDATION_EXPORT extern "C"
|
||||
#else
|
||||
#define FOUNDATION_EXPORT extern
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
17
PSCBOnlineSample/Pods/Target Support Files/PSCBOnline/PSCBOnline-umbrella.h
generated
Normal file
17
PSCBOnlineSample/Pods/Target Support Files/PSCBOnline/PSCBOnline-umbrella.h
generated
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifdef __OBJC__
|
||||
#import <UIKit/UIKit.h>
|
||||
#else
|
||||
#ifndef FOUNDATION_EXPORT
|
||||
#if defined(__cplusplus)
|
||||
#define FOUNDATION_EXPORT extern "C"
|
||||
#else
|
||||
#define FOUNDATION_EXPORT extern
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#import "PSCBOnline.h"
|
||||
|
||||
FOUNDATION_EXPORT double PSCBOnlineVersionNumber;
|
||||
FOUNDATION_EXPORT const unsigned char PSCBOnlineVersionString[];
|
||||
|
12
PSCBOnlineSample/Pods/Target Support Files/PSCBOnline/PSCBOnline.debug.xcconfig
generated
Normal file
12
PSCBOnlineSample/Pods/Target Support Files/PSCBOnline/PSCBOnline.debug.xcconfig
generated
Normal file
|
@ -0,0 +1,12 @@
|
|||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/PSCBOnline
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_ROOT = ${SRCROOT}
|
||||
PODS_TARGET_SRCROOT = ${PODS_ROOT}/PSCBOnline
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||
SKIP_INSTALL = YES
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
|
@ -0,0 +1,6 @@
|
|||
framework module PSCBOnline {
|
||||
umbrella header "PSCBOnline-umbrella.h"
|
||||
|
||||
export *
|
||||
module * { export * }
|
||||
}
|
12
PSCBOnlineSample/Pods/Target Support Files/PSCBOnline/PSCBOnline.release.xcconfig
generated
Normal file
12
PSCBOnlineSample/Pods/Target Support Files/PSCBOnline/PSCBOnline.release.xcconfig
generated
Normal file
|
@ -0,0 +1,12 @@
|
|||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/PSCBOnline
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_ROOT = ${SRCROOT}
|
||||
PODS_TARGET_SRCROOT = ${PODS_ROOT}/PSCBOnline
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||
SKIP_INSTALL = YES
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
|
@ -0,0 +1,26 @@
|
|||
<?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>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${CURRENT_PROJECT_VERSION}</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,8 @@
|
|||
# Acknowledgements
|
||||
This application makes use of the following third party libraries:
|
||||
|
||||
## PSCBOnline
|
||||
|
||||
LICENSE BE HERE
|
||||
|
||||
Generated by CocoaPods - https://cocoapods.org
|
|
@ -0,0 +1,40 @@
|
|||
<?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>PreferenceSpecifiers</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>This application makes use of the following third party libraries:</string>
|
||||
<key>Title</key>
|
||||
<string>Acknowledgements</string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>LICENSE BE HERE
|
||||
</string>
|
||||
<key>License</key>
|
||||
<string>PSCB</string>
|
||||
<key>Title</key>
|
||||
<string>PSCBOnline</string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>Generated by CocoaPods - https://cocoapods.org</string>
|
||||
<key>Title</key>
|
||||
<string></string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>StringsTable</key>
|
||||
<string>Acknowledgements</string>
|
||||
<key>Title</key>
|
||||
<string>Acknowledgements</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,5 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
@interface PodsDummy_Pods_PSCBOnlineSample_PSCBOnlineSampleUITests : NSObject
|
||||
@end
|
||||
@implementation PodsDummy_Pods_PSCBOnlineSample_PSCBOnlineSampleUITests
|
||||
@end
|
|
@ -0,0 +1,2 @@
|
|||
${PODS_ROOT}/Target Support Files/Pods-PSCBOnlineSample-PSCBOnlineSampleUITests/Pods-PSCBOnlineSample-PSCBOnlineSampleUITests-frameworks.sh
|
||||
${BUILT_PRODUCTS_DIR}/PSCBOnline/PSCBOnline.framework
|
|
@ -0,0 +1 @@
|
|||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PSCBOnline.framework
|
|
@ -0,0 +1,2 @@
|
|||
${PODS_ROOT}/Target Support Files/Pods-PSCBOnlineSample-PSCBOnlineSampleUITests/Pods-PSCBOnlineSample-PSCBOnlineSampleUITests-frameworks.sh
|
||||
${BUILT_PRODUCTS_DIR}/PSCBOnline/PSCBOnline.framework
|
|
@ -0,0 +1 @@
|
|||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PSCBOnline.framework
|
|
@ -0,0 +1,185 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
set -u
|
||||
set -o pipefail
|
||||
|
||||
function on_error {
|
||||
echo "$(realpath -mq "${0}"):$1: error: Unexpected failure"
|
||||
}
|
||||
trap 'on_error $LINENO' ERR
|
||||
|
||||
if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
|
||||
# If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
|
||||
# frameworks to, so exit 0 (signalling the script phase was successful).
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
|
||||
COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
|
||||
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
|
||||
BCSYMBOLMAP_DIR="BCSymbolMaps"
|
||||
|
||||
|
||||
# This protects against multiple targets copying the same framework dependency at the same time. The solution
|
||||
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
|
||||
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
|
||||
|
||||
# Copies and strips a vendored framework
|
||||
install_framework()
|
||||
{
|
||||
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
|
||||
local source="${BUILT_PRODUCTS_DIR}/$1"
|
||||
elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
|
||||
local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
|
||||
elif [ -r "$1" ]; then
|
||||
local source="$1"
|
||||
fi
|
||||
|
||||
local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
|
||||
if [ -L "${source}" ]; then
|
||||
echo "Symlinked..."
|
||||
source="$(readlink "${source}")"
|
||||
fi
|
||||
|
||||
if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then
|
||||
# Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied
|
||||
find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do
|
||||
echo "Installing $f"
|
||||
install_bcsymbolmap "$f" "$destination"
|
||||
rm "$f"
|
||||
done
|
||||
rmdir "${source}/${BCSYMBOLMAP_DIR}"
|
||||
fi
|
||||
|
||||
# Use filter instead of exclude so missing patterns don't throw errors.
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
|
||||
|
||||
local basename
|
||||
basename="$(basename -s .framework "$1")"
|
||||
binary="${destination}/${basename}.framework/${basename}"
|
||||
|
||||
if ! [ -r "$binary" ]; then
|
||||
binary="${destination}/${basename}"
|
||||
elif [ -L "${binary}" ]; then
|
||||
echo "Destination binary is symlinked..."
|
||||
dirname="$(dirname "${binary}")"
|
||||
binary="${dirname}/$(readlink "${binary}")"
|
||||
fi
|
||||
|
||||
# Strip invalid architectures so "fat" simulator / device frameworks work on device
|
||||
if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
|
||||
strip_invalid_archs "$binary"
|
||||
fi
|
||||
|
||||
# Resign the code if required by the build settings to avoid unstable apps
|
||||
code_sign_if_enabled "${destination}/$(basename "$1")"
|
||||
|
||||
# Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
|
||||
if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
|
||||
local swift_runtime_libs
|
||||
swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u)
|
||||
for lib in $swift_runtime_libs; do
|
||||
echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
|
||||
rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
|
||||
code_sign_if_enabled "${destination}/${lib}"
|
||||
done
|
||||
fi
|
||||
}
|
||||
# Copies and strips a vendored dSYM
|
||||
install_dsym() {
|
||||
local source="$1"
|
||||
warn_missing_arch=${2:-true}
|
||||
if [ -r "$source" ]; then
|
||||
# Copy the dSYM into the targets temp dir.
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
|
||||
|
||||
local basename
|
||||
basename="$(basename -s .dSYM "$source")"
|
||||
binary_name="$(ls "$source/Contents/Resources/DWARF")"
|
||||
binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}"
|
||||
|
||||
# Strip invalid architectures from the dSYM.
|
||||
if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then
|
||||
strip_invalid_archs "$binary" "$warn_missing_arch"
|
||||
fi
|
||||
if [[ $STRIP_BINARY_RETVAL == 0 ]]; then
|
||||
# Move the stripped file into its final destination.
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
|
||||
else
|
||||
# The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
|
||||
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Used as a return value for each invocation of `strip_invalid_archs` function.
|
||||
STRIP_BINARY_RETVAL=0
|
||||
|
||||
# Strip invalid architectures
|
||||
strip_invalid_archs() {
|
||||
binary="$1"
|
||||
warn_missing_arch=${2:-true}
|
||||
# Get architectures for current target binary
|
||||
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
|
||||
# Intersect them with the architectures we are building for
|
||||
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
|
||||
# If there are no archs supported by this binary then warn the user
|
||||
if [[ -z "$intersected_archs" ]]; then
|
||||
if [[ "$warn_missing_arch" == "true" ]]; then
|
||||
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
|
||||
fi
|
||||
STRIP_BINARY_RETVAL=1
|
||||
return
|
||||
fi
|
||||
stripped=""
|
||||
for arch in $binary_archs; do
|
||||
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
|
||||
# Strip non-valid architectures in-place
|
||||
lipo -remove "$arch" -output "$binary" "$binary"
|
||||
stripped="$stripped $arch"
|
||||
fi
|
||||
done
|
||||
if [[ "$stripped" ]]; then
|
||||
echo "Stripped $binary of architectures:$stripped"
|
||||
fi
|
||||
STRIP_BINARY_RETVAL=0
|
||||
}
|
||||
|
||||
# Copies the bcsymbolmap files of a vendored framework
|
||||
install_bcsymbolmap() {
|
||||
local bcsymbolmap_path="$1"
|
||||
local destination="${BUILT_PRODUCTS_DIR}"
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"
|
||||
}
|
||||
|
||||
# Signs a framework with the provided identity
|
||||
code_sign_if_enabled() {
|
||||
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
|
||||
# Use the current code_sign_identity
|
||||
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
|
||||
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
|
||||
|
||||
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
|
||||
code_sign_cmd="$code_sign_cmd &"
|
||||
fi
|
||||
echo "$code_sign_cmd"
|
||||
eval "$code_sign_cmd"
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ "$CONFIGURATION" == "Debug" ]]; then
|
||||
install_framework "${BUILT_PRODUCTS_DIR}/PSCBOnline/PSCBOnline.framework"
|
||||
fi
|
||||
if [[ "$CONFIGURATION" == "Release" ]]; then
|
||||
install_framework "${BUILT_PRODUCTS_DIR}/PSCBOnline/PSCBOnline.framework"
|
||||
fi
|
||||
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
|
||||
wait
|
||||
fi
|
|
@ -0,0 +1,16 @@
|
|||
#ifdef __OBJC__
|
||||
#import <UIKit/UIKit.h>
|
||||
#else
|
||||
#ifndef FOUNDATION_EXPORT
|
||||
#if defined(__cplusplus)
|
||||
#define FOUNDATION_EXPORT extern "C"
|
||||
#else
|
||||
#define FOUNDATION_EXPORT extern
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
FOUNDATION_EXPORT double Pods_PSCBOnlineSample_PSCBOnlineSampleUITestsVersionNumber;
|
||||
FOUNDATION_EXPORT const unsigned char Pods_PSCBOnlineSample_PSCBOnlineSampleUITestsVersionString[];
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PSCBOnline"
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PSCBOnline/PSCBOnline.framework/Headers"
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
|
||||
OTHER_LDFLAGS = $(inherited) -framework "PSCBOnline"
|
||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||
PODS_ROOT = ${SRCROOT}/Pods
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
|
@ -0,0 +1,6 @@
|
|||
framework module Pods_PSCBOnlineSample_PSCBOnlineSampleUITests {
|
||||
umbrella header "Pods-PSCBOnlineSample-PSCBOnlineSampleUITests-umbrella.h"
|
||||
|
||||
export *
|
||||
module * { export * }
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PSCBOnline"
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PSCBOnline/PSCBOnline.framework/Headers"
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
|
||||
OTHER_LDFLAGS = $(inherited) -framework "PSCBOnline"
|
||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||
PODS_ROOT = ${SRCROOT}/Pods
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
26
PSCBOnlineSample/Pods/Target Support Files/Pods-PSCBOnlineSample/Pods-PSCBOnlineSample-Info.plist
generated
Normal file
26
PSCBOnlineSample/Pods/Target Support Files/Pods-PSCBOnlineSample/Pods-PSCBOnlineSample-Info.plist
generated
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?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>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${CURRENT_PROJECT_VERSION}</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,8 @@
|
|||
# Acknowledgements
|
||||
This application makes use of the following third party libraries:
|
||||
|
||||
## PSCBOnline
|
||||
|
||||
LICENSE BE HERE
|
||||
|
||||
Generated by CocoaPods - https://cocoapods.org
|
|
@ -0,0 +1,40 @@
|
|||
<?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>PreferenceSpecifiers</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>This application makes use of the following third party libraries:</string>
|
||||
<key>Title</key>
|
||||
<string>Acknowledgements</string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>LICENSE BE HERE
|
||||
</string>
|
||||
<key>License</key>
|
||||
<string>PSCB</string>
|
||||
<key>Title</key>
|
||||
<string>PSCBOnline</string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>Generated by CocoaPods - https://cocoapods.org</string>
|
||||
<key>Title</key>
|
||||
<string></string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>StringsTable</key>
|
||||
<string>Acknowledgements</string>
|
||||
<key>Title</key>
|
||||
<string>Acknowledgements</string>
|
||||
</dict>
|
||||
</plist>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue