Skip to content
This repository has been archived by the owner on Jan 17, 2023. It is now read-only.

Fix nullability #4551

Merged
merged 1 commit into from
Apr 20, 2020
Merged

Fix nullability #4551

merged 1 commit into from
Apr 20, 2020

Conversation

ElfSundae
Copy link
Contributor

No description provided.

Copy link
Member

@jshier jshier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dataTaskWithHTTPMethod matches the other methods, but the other changes seem unnecessary. Please provide a full explanation and tests that exercise these changes.

@@ -216,7 +216,7 @@ forHTTPHeaderField:(NSString *)field;

@param block A block that defines a process of encoding parameters into a query string. This block returns the query string and takes three arguments: the request, the parameters to encode, and the error that occurred when attempting to encode parameters for the given request.
*/
- (void)setQueryStringSerializationWithBlock:(nullable NSString * (^)(NSURLRequest *request, id parameters, NSError * __autoreleasing *error))block;
- (void)setQueryStringSerializationWithBlock:(nullable NSString * _Nullable (^)(NSURLRequest *request, id parameters, NSError * __autoreleasing *error))block;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems redundant: the NSString return value is already nullable, this is just the same annotation spelled another way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nullable is for the method parameter, so you can pass nil to this method: setWithBlock:nil.
_Nullable is for the return value of the block, so you can return nil in the block if any serialization error occurs:

setWithBlock:^NSString * _Nullable (...) {
    *error = [NSError errorWith...];
    return nil;
}

Copy link
Member

@jshier jshier Apr 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the block syntax is as follows: (returnType (^nullability)(parameterTypes))blockName;. So the code currently allows for returning nil just fine, but does require the block. So what's the reason for the change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you may have made a mistake.

Yes, nullability returnType (^) ... is equivalent to returnType (^nullability) ... . But this nullability is a qualifier for the whole block, and the block is a parameter of the setQueryStringSerializationWithBlock: method. That means this method accepts one parameter and the parameter can be nullability (nil is this case).

The code currently allows for returning nil

Not returning nil, but passing nil.

Users may pass a block to customize the query string serialization, or pass nil to reset it to use the default serialization provided by AFURLRequestSerialization.

I added _Nullable for the return type of the block, because the block can return nil if any error occurs.

You may test current return type of the block via Xcode Autocompletion:

[[AFHTTPRequestSerializer serializer]
    setQueryStringSerializationWithBlock:^NSString * _Nonnull(NSURLRequest * _Nonnull request, id  _Nonnull parameters, NSError *__autoreleasing  _Nullable * _Nullable error) {

}];

You may check out setDownloadTaskDidFinishDownloadingBlock it also follows this style nullable blockReturnType _Nullable (^)....

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears you're correct. The first nullable controls the nullability of the block, the _Nullable controls the nullability of the return value.

AFNetworking/AFURLRequestSerialization.h Show resolved Hide resolved
AFNetworking/AFHTTPSessionManager.h Show resolved Hide resolved
downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgress
success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
- (nullable NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you ensure the implementations have matching nullability as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked all dataTaskWith..., requestWith... and RESTful methods in the session manager and the request serializer. The others have correct nullability except for these two methods.

In addition, accurately, the multipart POST method will never return nil. The multipart POST method invokes [self.requestSerializer multipartFormRequestWithMethod:...] which returns nonnull becuase it passes nil as parameters to -requestWithMethod:URLString:parameters:error that won't cause an serializationError.

Then we have three options:

Option 1: add nullable to the return type for -multipartFormRequestWithMethod, to match other request generator methods. And check the return value from requestWithMethod:

  NSMutableURLRequest *mutableRequest = [self requestWithMethod:method ..

+ if (!mutableRequest) {
+    return nil;
+ }

  // append multiparts

Option 2: remove nullable from the multipart POST method. And remove the serializationError checker?

- NSError *serializationError = nil;
  NSMutableURLRequest *request = [self.requestSerializer multipartFormRequestWithMethod... 
+                                   error:NULL];
- if (serializationError) {
-    if (failure) {
-         dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
-            failure(nil, serializationError);
-        });
-    }
-
-     return nil;
- }

 // create task

Option 3: change nothing :)

This PR chooses the third option, now I prefer option 1, what do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That seems fine for now, it can be updated if necessary in the future.

@jshier jshier merged commit f19335f into AFNetworking:master Apr 20, 2020
@jshier jshier added this to the 4.0.1 milestone Apr 20, 2020
jshier pushed a commit that referenced this pull request Apr 20, 2020
jshier added a commit that referenced this pull request Apr 20, 2020
* Fix serverTrust crash (#4542)

* Update readme, add stale bot, add issue template, add pull request template

* Update copy from Alamofire

* Fix crash on nil serverTrust

* Expose server trust error

* add test for error throws

* Fix nullability

* Fix evaluateServerTrust determination (#4552)

Co-authored-by: Jon Shier <jon@jonshier.com>

* Revert changes making error generation public.

This reverts commit 111352b.

# Conflicts:
#	AFNetworking/AFURLSessionManager.m

* Make static error function a method instead.

* Make trust generatio part of AFTestCase.

* Add test cases for server trust error generation.

* Mark parameters explicitly nullable.

* Fix nullability (#4551)

* Replace instead of appending to the default header (#4550)

* Replace instead of appending to the default header

* Add tests for setting HTTP headers per request

* Fix SPM usage with better publicHeadersPath. (#4554)

Co-authored-by: Jakub Kašpar <kaspikk@gmail.com>
Co-authored-by: Elf Sundae <elf.sundae@gmail.com>
@ElfSundae ElfSundae deleted the fix-nullability branch April 21, 2020 08:39
parkboo added a commit to parkboo/AFNetworking that referenced this pull request Sep 22, 2020
* commit '77ef5fed64d98107acd177a90182163a20ba4567': (31 commits)
  Use low priority queue instead of background for SCNetworkReachabilityGetFlags() (AFNetworking#4587)
  Exempt "needs investigation" from stalebot.
  Only mark unlabeled issues as stale.
  Loop over only changed keypaths in request serializer (AFNetworking#4581)
  Disable 'Zombie Objects' diagnostics for tvOS scheme (AFNetworking#4572)
  Fix docblock for setAuthenticationChallengeHandler (AFNetworking#4574)
  Fix type in CHANGELOG. (AFNetworking#4562)
  Prepare 4.0.1 Release (AFNetworking#4555)
  Fix ServerTrustError crash. (AFNetworking#4553)
  Fix SPM usage with better publicHeadersPath. (AFNetworking#4554)
  Replace instead of appending to the default header (AFNetworking#4550)
  Fix nullability (AFNetworking#4551)
  Update CHANGELOG.md (AFNetworking#4537)
  Fix UIKit+AFNetworking.h (AFNetworking#4536)
  Remove unused UIImage+AFNetworking.h (AFNetworking#4535)
  Separate bundle identifier for watchOS target (AFNetworking#4533)
  Fix MobileCoreServices renamed warning, close #4520 (AFNetworking#4532)
  Add FOUNDATION_EXPORT for AFJSONObjectByRemovingKeysWithNullValues (AFNetworking#4529)
  (Infra) Make infra changes to cleanup project and simplify its maintenance (AFNetworking#4531)
  Improve podspec (AFNetworking#4528)
  ...

# Conflicts:
#	Framework/AFNetworking.h
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants