Skip to content

Allow custom objectIds #100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Mar 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ coverage:
changes: false
project:
default:
target: 76
target: 80
comment:
require_changes: true
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
# Parse-Swift Changelog

### main
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.2.1...main)
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.2.2...main)
* _Contributing to this repo? Add info about your change here to be included in the next release_


### 1.2.2
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.2.1...1.2.2)

__New features__
- Allow custom objectIds ([#100](https://github.com/parse-community/Parse-Swift/pull/100)), thanks to [Corey Baker](https://github.com/cbaker6).
- Add ParseTwitter and ParseFacebook authentication ([#97](https://github.com/parse-community/Parse-Swift/pull/97)), thanks to [Abdulaziz Alhomaidhi](https://github.com/abs8090).
- Add build support for Android ([#90](https://github.com/parse-community/Parse-Swift/pull/90)), thanks to [jt9897253](https://github.com/jt9897253).

__Fixes__
- There was another bug after a user first logs in anonymously and then becomes a real user. The authData sent to the server wasn't stripped, keep the user anonymous instead of making them a real user ([#100](https://github.com/parse-community/Parse-Swift/pull/100)), thanks to [Corey Baker](https://github.com/cbaker6).

### 1.2.1
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.2.0...1.2.1)
Expand Down
2 changes: 1 addition & 1 deletion ParseSwift.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "ParseSwift"
s.version = "1.2.1"
s.version = "1.2.2"
s.summary = "Parse Pure Swift SDK"
s.homepage = "https://github.com/parse-community/Parse-Swift"
s.authors = {
Expand Down
24 changes: 16 additions & 8 deletions ParseSwift.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@
70647E9D259E3A9A004C1004 /* ParseType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70647E9B259E3A9A004C1004 /* ParseType.swift */; };
70647E9E259E3A9A004C1004 /* ParseType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70647E9B259E3A9A004C1004 /* ParseType.swift */; };
70647E9F259E3A9A004C1004 /* ParseType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70647E9B259E3A9A004C1004 /* ParseType.swift */; };
70732C5A2606CCAD000CAB81 /* ParseObjectCustomObjectId.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70732C592606CCAD000CAB81 /* ParseObjectCustomObjectId.swift */; };
70732C5B2606CCAD000CAB81 /* ParseObjectCustomObjectId.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70732C592606CCAD000CAB81 /* ParseObjectCustomObjectId.swift */; };
70732C5C2606CCAD000CAB81 /* ParseObjectCustomObjectId.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70732C592606CCAD000CAB81 /* ParseObjectCustomObjectId.swift */; };
707A3BF125B0A4F0000D215C /* ParseAuthentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 707A3BF025B0A4F0000D215C /* ParseAuthentication.swift */; };
707A3BF225B0A4F0000D215C /* ParseAuthentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 707A3BF025B0A4F0000D215C /* ParseAuthentication.swift */; };
707A3BF325B0A4F0000D215C /* ParseAuthentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 707A3BF025B0A4F0000D215C /* ParseAuthentication.swift */; };
Expand Down Expand Up @@ -599,6 +602,7 @@
705D950725BE4C08003EF6F8 /* SubscriptionCallback.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionCallback.swift; sourceTree = "<group>"; };
70647E8D259E3375004C1004 /* LocallyIdentifiable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocallyIdentifiable.swift; sourceTree = "<group>"; };
70647E9B259E3A9A004C1004 /* ParseType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseType.swift; sourceTree = "<group>"; };
70732C592606CCAD000CAB81 /* ParseObjectCustomObjectId.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseObjectCustomObjectId.swift; sourceTree = "<group>"; };
707A3BF025B0A4F0000D215C /* ParseAuthentication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseAuthentication.swift; sourceTree = "<group>"; };
707A3C1025B0A8E8000D215C /* ParseAnonymous.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseAnonymous.swift; sourceTree = "<group>"; };
707A3C1F25B14BCF000D215C /* ParseApple.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseApple.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -830,6 +834,7 @@
7003963A25A288100052CB31 /* ParseLiveQueryTests.swift */,
70C7DC2024D20F190050419B /* ParseObjectBatchTests.swift */,
7044C1DE25C5C70D0011F6E7 /* ParseObjectCombine.swift */,
70732C592606CCAD000CAB81 /* ParseObjectCustomObjectId.swift */,
911DB13524C4FC100027F3C7 /* ParseObjectTests.swift */,
7044C1EB25C5CC930011F6E7 /* ParseOperationCombineTests.swift */,
70C5508425B4A68700B5DBC2 /* ParseOperationTests.swift */,
Expand Down Expand Up @@ -1660,6 +1665,7 @@
89899D772603CF66002E2043 /* ParseFacebookTests.swift in Sources */,
70386A4625D99C8B0048EC1B /* ParseLDAPTests.swift in Sources */,
911DB12E24C4837E0027F3C7 /* APICommandTests.swift in Sources */,
70732C5A2606CCAD000CAB81 /* ParseObjectCustomObjectId.swift in Sources */,
911DB12C24C3F7720027F3C7 /* MockURLResponse.swift in Sources */,
7044C24325C5EA360011F6E7 /* ParseAppleCombineTests.swift in Sources */,
7044C1DF25C5C70D0011F6E7 /* ParseObjectCombine.swift in Sources */,
Expand Down Expand Up @@ -1810,6 +1816,7 @@
89899D822603CF67002E2043 /* ParseFacebookTests.swift in Sources */,
70386A4825D99C8B0048EC1B /* ParseLDAPTests.swift in Sources */,
709B984C2556ECAA00507778 /* APICommandTests.swift in Sources */,
70732C5C2606CCAD000CAB81 /* ParseObjectCustomObjectId.swift in Sources */,
709B984D2556ECAA00507778 /* AnyDecodableTests.swift in Sources */,
7044C24525C5EA360011F6E7 /* ParseAppleCombineTests.swift in Sources */,
7044C1E125C5C70D0011F6E7 /* ParseObjectCombine.swift in Sources */,
Expand Down Expand Up @@ -1863,6 +1870,7 @@
89899D812603CF67002E2043 /* ParseFacebookTests.swift in Sources */,
70386A4725D99C8B0048EC1B /* ParseLDAPTests.swift in Sources */,
70F2E2B5254F283000B2EA5C /* ParseEncoderTests.swift in Sources */,
70732C5B2606CCAD000CAB81 /* ParseObjectCustomObjectId.swift in Sources */,
70F2E2C2254F283000B2EA5C /* APICommandTests.swift in Sources */,
7044C24425C5EA360011F6E7 /* ParseAppleCombineTests.swift in Sources */,
7044C1E025C5C70D0011F6E7 /* ParseObjectCombine.swift in Sources */,
Expand Down Expand Up @@ -2313,7 +2321,7 @@
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MARKETING_VERSION = 1.2.1;
MARKETING_VERSION = 1.2.2;
PRODUCT_BUNDLE_IDENTIFIER = com.parse.ParseSwift;
PRODUCT_NAME = ParseSwift;
SKIP_INSTALL = YES;
Expand All @@ -2337,7 +2345,7 @@
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MARKETING_VERSION = 1.2.1;
MARKETING_VERSION = 1.2.2;
PRODUCT_BUNDLE_IDENTIFIER = com.parse.ParseSwift;
PRODUCT_NAME = ParseSwift;
SKIP_INSTALL = YES;
Expand Down Expand Up @@ -2403,7 +2411,7 @@
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 1.2.1;
MARKETING_VERSION = 1.2.2;
PRODUCT_BUNDLE_IDENTIFIER = com.parse.ParseSwift;
PRODUCT_NAME = ParseSwift;
SDKROOT = macosx;
Expand All @@ -2429,7 +2437,7 @@
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 1.2.1;
MARKETING_VERSION = 1.2.2;
PRODUCT_BUNDLE_IDENTIFIER = com.parse.ParseSwift;
PRODUCT_NAME = ParseSwift;
SDKROOT = macosx;
Expand Down Expand Up @@ -2576,7 +2584,7 @@
INFOPLIST_FILE = "ParseSwift-watchOS/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MARKETING_VERSION = 1.2.1;
MARKETING_VERSION = 1.2.2;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.parse.ParseSwift-watchOS";
Expand Down Expand Up @@ -2605,7 +2613,7 @@
INFOPLIST_FILE = "ParseSwift-watchOS/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MARKETING_VERSION = 1.2.1;
MARKETING_VERSION = 1.2.2;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.parse.ParseSwift-watchOS";
PRODUCT_NAME = ParseSwift;
Expand All @@ -2632,7 +2640,7 @@
INFOPLIST_FILE = "ParseSwift-tvOS/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MARKETING_VERSION = 1.2.1;
MARKETING_VERSION = 1.2.2;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.parse.ParseSwift-tvOS";
Expand Down Expand Up @@ -2660,7 +2668,7 @@
INFOPLIST_FILE = "ParseSwift-tvOS/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MARKETING_VERSION = 1.2.1;
MARKETING_VERSION = 1.2.2;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.parse.ParseSwift-tvOS";
PRODUCT_NAME = ParseSwift;
Expand Down
2 changes: 1 addition & 1 deletion Scripts/jazzy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ bundle exec jazzy \
--author_url http://parseplatform.org \
--github_url https://github.com/parse-community/Parse-Swift \
--root-url http://parseplatform.org/Parse-Swift/api/ \
--module-version 1.2.1 \
--module-version 1.2.2 \
--theme fullwidth \
--skip-undocumented \
--output ./docs/api \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,12 @@ public extension ParseUser {
static func login(_ type: String,
authData: [String: String],
options: API.Options) throws -> Self {
let body = SignupLoginBody(authData: [type: authData])
return try signupCommand(body: body).execute(options: options)
if Self.current != nil {
return try Self.link(type, authData: authData, options: options)
} else {
let body = SignupLoginBody(authData: [type: authData])
return try signupCommand(body: body).execute(options: options)
}
}

/**
Expand All @@ -238,22 +242,28 @@ public extension ParseUser {
options: API.Options,
callbackQueue: DispatchQueue = .main,
completion: @escaping (Result<Self, ParseError>) -> Void) {

let body = SignupLoginBody(authData: [type: authData])
do {
try signupCommand(body: body)
.executeAsync(options: options) { result in
callbackQueue.async {
completion(result)
if Self.current != nil {
Self.link(type, authData: authData,
options: options,
callbackQueue: callbackQueue,
completion: completion)
} else {
let body = SignupLoginBody(authData: [type: authData])
do {
try signupCommand(body: body)
.executeAsync(options: options) { result in
callbackQueue.async {
completion(result)
}
}
} catch {
callbackQueue.async {
if let parseError = error as? ParseError {
completion(.failure(parseError))
} else {
let parseError = ParseError(code: .unknownError, message: error.localizedDescription)
completion(.failure(parseError))
}
}
} catch {
callbackQueue.async {
if let parseError = error as? ParseError {
completion(.failure(parseError))
} else {
let parseError = ParseError(code: .unknownError, message: error.localizedDescription)
completion(.failure(parseError))
}
}
}
Expand Down Expand Up @@ -384,29 +394,47 @@ public extension ParseUser {
}
}

internal func linkCommand() -> API.NonParseBodyCommand<Self, Self> {
Self.current?.anonymous.strip()
return API.NonParseBodyCommand<Self, Self>(method: .PUT,
path: endpoint,
body: Self.current) { (data) -> Self in
let user = try ParseCoding.jsonDecoder().decode(UpdateSessionTokenResponse.self, from: data)
Self.current?.updatedAt = user.updatedAt
guard let current = Self.current else {
throw ParseError(code: .unknownError, message: "Should have a current user.")
}
Self.currentUserContainer = .init(currentUser: current,
sessionToken: user.sessionToken)
Self.saveCurrentContainerToKeychain()
return current
}
}

internal func linkCommand(body: SignupLoginBody) -> API.NonParseBodyCommand<SignupLoginBody, Self> {
var body = body
Self.current?.anonymous.strip()
if var currentAuthData = Self.current?.authData {
if let bodyAuthData = body.authData {
bodyAuthData.forEach { (key, value) in
currentAuthData[key] = value
}
}
body.authData = currentAuthData
}

return API.NonParseBodyCommand<SignupLoginBody, Self>(method: .PUT,
path: endpoint,
body: body) { (data) -> Self in
let user = try ParseCoding.jsonDecoder().decode(Self.self, from: data)
if let authData = body.authData {
Self.current?.anonymous.strip()
if Self.current?.authData == nil {
Self.current?.authData = authData
} else {
authData.forEach { (key, value) in
Self.current?.authData?[key] = value
}
}
if let updatedAt = user.updatedAt {
Self.current?.updatedAt = updatedAt
}
}
Self.saveCurrentContainerToKeychain()
let user = try ParseCoding.jsonDecoder().decode(UpdateSessionTokenResponse.self, from: data)
Self.current?.updatedAt = user.updatedAt
Self.current?.authData = body.authData
guard let current = Self.current else {
throw ParseError(code: .unknownError, message: "Should have a current user.")
}
Self.currentUserContainer = .init(currentUser: current,
sessionToken: user.sessionToken)
Self.saveCurrentContainerToKeychain()
return current
}
}
Expand Down
19 changes: 17 additions & 2 deletions Sources/ParseSwift/Coding/ParseEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,16 @@ public struct ParseEncoder {
case object
case cloud
case none
case customObjectId
case custom(Set<String>)

func keys() -> Set<String> {
switch self {

case .object:
return Set(["createdAt", "updatedAt", "objectId", "className"])
case .customObjectId:
return Set(["createdAt", "updatedAt", "className"])
case .cloud:
return Set(["functionJobName"])
case .none:
Expand Down Expand Up @@ -99,7 +102,13 @@ public struct ParseEncoder {
internal func encode<T: ParseObject>(_ value: T,
objectsSavedBeforeThisOne: [String: PointerType]?,
filesSavedBeforeThisOne: [UUID: ParseFile]?) throws -> (encoded: Data, unique: Set<UniqueObject>, unsavedChildren: [Encodable]) {
let encoder = _ParseEncoder(codingPath: [], dictionary: NSMutableDictionary(), skippingKeys: SkippedKeys.object.keys())
let keysToSkip: Set<String>!
if !ParseConfiguration.allowCustomObjectId {
keysToSkip = SkippedKeys.object.keys()
} else {
keysToSkip = SkippedKeys.customObjectId.keys()
}
let encoder = _ParseEncoder(codingPath: [], dictionary: NSMutableDictionary(), skippingKeys: keysToSkip)
if let dateEncodingStrategy = dateEncodingStrategy {
encoder.dateEncodingStrategy = dateEncodingStrategy
}
Expand All @@ -110,7 +119,13 @@ public struct ParseEncoder {
internal func encode(_ value: ParseType, collectChildren: Bool,
objectsSavedBeforeThisOne: [String: PointerType]?,
filesSavedBeforeThisOne: [UUID: ParseFile]?) throws -> (encoded: Data, unique: Set<UniqueObject>, unsavedChildren: [Encodable]) {
let encoder = _ParseEncoder(codingPath: [], dictionary: NSMutableDictionary(), skippingKeys: SkippedKeys.object.keys())
let keysToSkip: Set<String>!
if !ParseConfiguration.allowCustomObjectId {
keysToSkip = SkippedKeys.object.keys()
} else {
keysToSkip = SkippedKeys.customObjectId.keys()
}
let encoder = _ParseEncoder(codingPath: [], dictionary: NSMutableDictionary(), skippingKeys: keysToSkip)
if let dateEncodingStrategy = dateEncodingStrategy {
encoder.dateEncodingStrategy = dateEncodingStrategy
}
Expand Down
Loading