Skip to content

Commit

Permalink
Merge pull request #135 from lewis-smith/master
Browse files Browse the repository at this point in the history
Moved to stringByAddingPercentEncodingWithAllowedCharacters
  • Loading branch information
zntfdr committed Feb 24, 2016
2 parents a2f88ee + 1e65ace commit 9a82b6c
Show file tree
Hide file tree
Showing 8 changed files with 258 additions and 17 deletions.
116 changes: 115 additions & 1 deletion Swifter.xcodeproj/project.pbxproj
Expand Up @@ -82,6 +82,9 @@
A1C7F0A51C7845FD00955ADB /* SwifterMac.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B9F51131944A61D00894629 /* SwifterMac.framework */; };
A1C7F0A61C7845FD00955ADB /* SwifterMac.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B9F51131944A61D00894629 /* SwifterMac.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
A1DD65C51B618D7E0070E6FC /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A1DD65C41B618D7E0070E6FC /* Launch Screen.storyboard */; };
F6B4D5781C7BAC4500E06514 /* SwifterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6B4D5771C7BAC4500E06514 /* SwifterTests.swift */; };
F6B4D57A1C7BAC4500E06514 /* SwifteriOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B9F50EE1944A5AB00894629 /* SwifteriOS.framework */; };
F6B4D5811C7BAC5E00E06514 /* String+SwifterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6B4D5801C7BAC5E00E06514 /* String+SwifterTests.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand All @@ -99,6 +102,13 @@
remoteGlobalIDString = 8B9F51121944A61D00894629;
remoteInfo = SwifterMac;
};
F6B4D57B1C7BAC4500E06514 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 8B9F50E51944A5AB00894629 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 8B9F50ED1944A5AB00894629;
remoteInfo = SwifteriOS;
};
/* End PBXContainerItemProxy section */

/* Begin PBXCopyFilesBuildPhase section */
Expand Down Expand Up @@ -175,6 +185,10 @@
8BF1D6871948C11E00E3AA64 /* SwifterCredential.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwifterCredential.swift; sourceTree = "<group>"; };
A17A694D1C78333400063DFD /* Operator+Swifter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Operator+Swifter.swift"; sourceTree = "<group>"; };
A1DD65C41B618D7E0070E6FC /* Launch Screen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = "Launch Screen.storyboard"; path = "../Swifter/Launch Screen.storyboard"; sourceTree = "<group>"; };
F6B4D5751C7BAC4500E06514 /* SwifterTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SwifterTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
F6B4D5771C7BAC4500E06514 /* SwifterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwifterTests.swift; sourceTree = "<group>"; };
F6B4D5791C7BAC4500E06514 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
F6B4D5801C7BAC5E00E06514 /* String+SwifterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+SwifterTests.swift"; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -208,6 +222,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
F6B4D5721C7BAC4500E06514 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
F6B4D57A1C7BAC4500E06514 /* SwifteriOS.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
Expand Down Expand Up @@ -268,6 +290,7 @@
8B9F51461944A8DC00894629 /* Swifter */,
8B300C201944AA1A00993175 /* SwifterDemoiOS */,
8B300C481944AECB00993175 /* SwifterDemoMac */,
F6B4D5761C7BAC4500E06514 /* SwifterTests */,
8B9F50EF1944A5AB00894629 /* Products */,
);
sourceTree = "<group>";
Expand All @@ -279,6 +302,7 @@
8B9F51131944A61D00894629 /* SwifterMac.framework */,
8B300C1F1944AA1A00993175 /* SwifterDemoiOS.app */,
8B300C471944AECB00993175 /* SwifterDemoMac.app */,
F6B4D5751C7BAC4500E06514 /* SwifterTests.xctest */,
);
name = Products;
sourceTree = "<group>";
Expand Down Expand Up @@ -329,6 +353,16 @@
name = Extensions;
sourceTree = "<group>";
};
F6B4D5761C7BAC4500E06514 /* SwifterTests */ = {
isa = PBXGroup;
children = (
F6B4D5801C7BAC5E00E06514 /* String+SwifterTests.swift */,
F6B4D5771C7BAC4500E06514 /* SwifterTests.swift */,
F6B4D5791C7BAC4500E06514 /* Info.plist */,
);
path = SwifterTests;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXHeadersBuildPhase section */
Expand Down Expand Up @@ -427,14 +461,32 @@
productReference = 8B9F51131944A61D00894629 /* SwifterMac.framework */;
productType = "com.apple.product-type.framework";
};
F6B4D5741C7BAC4500E06514 /* SwifterTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = F6B4D57F1C7BAC4500E06514 /* Build configuration list for PBXNativeTarget "SwifterTests" */;
buildPhases = (
F6B4D5711C7BAC4500E06514 /* Sources */,
F6B4D5721C7BAC4500E06514 /* Frameworks */,
F6B4D5731C7BAC4500E06514 /* Resources */,
);
buildRules = (
);
dependencies = (
F6B4D57C1C7BAC4500E06514 /* PBXTargetDependency */,
);
name = SwifterTests;
productName = SwifterTests;
productReference = F6B4D5751C7BAC4500E06514 /* SwifterTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
8B9F50E51944A5AB00894629 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftMigration = 0700;
LastSwiftUpdateCheck = 0700;
LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 0700;
ORGANIZATIONNAME = "Matt Donnelly";
TargetAttributes = {
Expand All @@ -450,6 +502,9 @@
8B9F51121944A61D00894629 = {
CreatedOnToolsVersion = 6.0;
};
F6B4D5741C7BAC4500E06514 = {
CreatedOnToolsVersion = 7.2;
};
};
};
buildConfigurationList = 8B9F50E81944A5AB00894629 /* Build configuration list for PBXProject "Swifter" */;
Expand All @@ -469,6 +524,7 @@
8B9F50ED1944A5AB00894629 /* SwifteriOS */,
8B9F51121944A61D00894629 /* SwifterMac */,
8B300C461944AECB00993175 /* SwifterDemoMac */,
F6B4D5741C7BAC4500E06514 /* SwifterTests */,
);
};
/* End PBXProject section */
Expand Down Expand Up @@ -507,6 +563,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
F6B4D5731C7BAC4500E06514 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
Expand Down Expand Up @@ -600,6 +663,15 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
F6B4D5711C7BAC4500E06514 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F6B4D5781C7BAC4500E06514 /* SwifterTests.swift in Sources */,
F6B4D5811C7BAC5E00E06514 /* String+SwifterTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */

/* Begin PBXTargetDependency section */
Expand All @@ -613,6 +685,11 @@
target = 8B9F51121944A61D00894629 /* SwifterMac */;
targetProxy = A1C7F0A71C7845FD00955ADB /* PBXContainerItemProxy */;
};
F6B4D57C1C7BAC4500E06514 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 8B9F50ED1944A5AB00894629 /* SwifteriOS */;
targetProxy = F6B4D57B1C7BAC4500E06514 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */

/* Begin PBXVariantGroup section */
Expand Down Expand Up @@ -866,6 +943,35 @@
};
name = Release;
};
F6B4D57D1C7BAC4500E06514 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
DEBUG_INFORMATION_FORMAT = dwarf;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = SwifterTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.2;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_ENABLE_DEBUG_INFO = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.mattdonnelly.SwifteriOS.SwifterTests;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
F6B4D57E1C7BAC4500E06514 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = SwifterTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.2;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = com.mattdonnelly.SwifteriOS.SwifterTests;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
Expand Down Expand Up @@ -914,6 +1020,14 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F6B4D57F1C7BAC4500E06514 /* Build configuration list for PBXNativeTarget "SwifterTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F6B4D57D1C7BAC4500E06514 /* Debug */,
F6B4D57E1C7BAC4500E06514 /* Release */,
);
defaultConfigurationIsVisible = 0;
};
/* End XCConfigurationList section */
};
rootObject = 8B9F50E51944A5AB00894629 /* Project object */;
Expand Down
4 changes: 2 additions & 2 deletions Swifter/Dictionary+Swifter.swift
Expand Up @@ -52,8 +52,8 @@ extension Dictionary {
var parts = [String]()

for (key, value) in self {
let keyString: String = "\(key)".urlEncodedStringWithEncoding(encoding)
let valueString: String = "\(value)".urlEncodedStringWithEncoding(encoding)
let keyString: String = "\(key)".urlEncodedStringWithEncoding()
let valueString: String = "\(value)".urlEncodedStringWithEncoding()
let query: String = "\(keyString)=\(valueString)"
parts.append(query)
}
Expand Down
13 changes: 5 additions & 8 deletions Swifter/String+Swifter.swift
Expand Up @@ -42,15 +42,12 @@ extension String {
}
}

func urlEncodedStringWithEncoding(encoding: NSStringEncoding) -> String {
let charactersToBeEscaped = ":/?&=;+!@#$()',*" as CFStringRef
let charactersToLeaveUnescaped = "[]." as CFStringRef
func urlEncodedStringWithEncoding() -> String {
let allowedCharacterSet = NSCharacterSet.URLQueryAllowedCharacterSet().mutableCopy() as! NSMutableCharacterSet
allowedCharacterSet.removeCharactersInString("\n:#/?@!$&'()*+,;=")
allowedCharacterSet.addCharactersInString("[]")
return self.stringByAddingPercentEncodingWithAllowedCharacters(allowedCharacterSet)!

let str = self as NSString

let result = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, str as CFString, charactersToLeaveUnescaped, charactersToBeEscaped, CFStringConvertNSStringEncodingToEncoding(encoding)) as NSString

return result as String
}

func parametersFromQueryString() -> Dictionary<String, String> {
Expand Down
4 changes: 2 additions & 2 deletions Swifter/SwifterAppOnlyClient.swift
Expand Up @@ -79,8 +79,8 @@ internal class SwifterAppOnlyClient: SwifterClientProtocol {
}

class func base64EncodedCredentialsWithKey(key: String, secret: String) -> String {
let encodedKey = key.urlEncodedStringWithEncoding(NSUTF8StringEncoding)
let encodedSecret = secret.urlEncodedStringWithEncoding(NSUTF8StringEncoding)
let encodedKey = key.urlEncodedStringWithEncoding()
let encodedSecret = secret.urlEncodedStringWithEncoding()
let bearerTokenCredentials = "\(encodedKey):\(encodedSecret)"
if let data = bearerTokenCredentials.dataUsingEncoding(NSUTF8StringEncoding) {
return data.base64EncodedStringWithOptions([])
Expand Down
8 changes: 4 additions & 4 deletions Swifter/SwifterOAuthClient.swift
Expand Up @@ -146,19 +146,19 @@ internal class SwifterOAuthClient: SwifterClientProtocol {
}

func oauthSignatureForMethod(method: HTTPMethodType, url: NSURL, parameters: Dictionary<String, Any>, accessToken token: SwifterCredential.OAuthAccessToken?) -> String {
let tokenSecret: NSString = token?.secret.urlEncodedStringWithEncoding(self.dataEncoding) ?? ""
let tokenSecret: NSString = token?.secret.urlEncodedStringWithEncoding() ?? ""

let encodedConsumerSecret = self.consumerSecret.urlEncodedStringWithEncoding(self.dataEncoding)
let encodedConsumerSecret = self.consumerSecret.urlEncodedStringWithEncoding()

let signingKey = "\(encodedConsumerSecret)&\(tokenSecret)"

var parameterComponents = parameters.urlEncodedQueryStringWithEncoding(self.dataEncoding).componentsSeparatedByString("&") as [String]
parameterComponents.sortInPlace { $0 < $1 }

let parameterString = parameterComponents.joinWithSeparator("&")
let encodedParameterString = parameterString.urlEncodedStringWithEncoding(self.dataEncoding)
let encodedParameterString = parameterString.urlEncodedStringWithEncoding()

let encodedURL = url.absoluteString.urlEncodedStringWithEncoding(self.dataEncoding)
let encodedURL = url.absoluteString.urlEncodedStringWithEncoding()

let signatureBaseString = "\(method)&\(encodedURL)&\(encodedParameterString)"

Expand Down
24 changes: 24 additions & 0 deletions SwifterTests/Info.plist
@@ -0,0 +1,24 @@
<?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>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
71 changes: 71 additions & 0 deletions SwifterTests/String+SwifterTests.swift
@@ -0,0 +1,71 @@
//
// String+SwifterTests.swift
// Swifter
//
// Created by Lewis Smith on 20/02/2016.
// Copyright © 2016 Matt Donnelly. All rights reserved.
//

import XCTest

@testable import SwifteriOS

class String_SwifterTests: XCTestCase {


override func setUp() {

super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.

}

override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}

func testEncoding() {

let shouldBeTheSameAfterEncoding = [
"a": "a",
"a a": "a%20a",
".": ".",
"[": "[",
"]": "]",
"'": "%27",
"$": "%24",
"&": "%26",
"<": "%3C",
">": "%3E",
"?": "%3F",
";": "%3B",
"#": "%23",
":": "%3A",
"=": "%3D",
",": "%2C",
"\"": "%22",
"+": "%2B",
"%": "%25",
":/?&=;+!@# ()',*": "%3A%2F%3F%26%3D%3B%2B%21%40%23%20%28%29%27%2C%2A",
"http://a?a=[a,b]": "http%3A%2F%2Fa%3Fa%3D[a%2Cb]"
]

let shouldBeDifferentAfterEcoding = [
"a": "b",
"a a": "a a",
"$": "$"
]

for (input, output) in shouldBeTheSameAfterEncoding {
XCTAssertEqual(input.urlEncodedStringWithEncoding(), output, input)
}


for (input, output) in shouldBeDifferentAfterEcoding {
XCTAssertNotEqual(input.urlEncodedStringWithEncoding(), output)
}
}


}

0 comments on commit 9a82b6c

Please sign in to comment.