[Foundation] Enable nullability in NSUrlSessionHandler. (#14597)

This commit is contained in:
Rolf Bjarne Kvinge 2022-04-01 14:48:57 +02:00 коммит произвёл GitHub
Родитель 1c4a64c0c4
Коммит e191c613ce
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 91 добавлений и 91 удалений

Просмотреть файл

@ -39,6 +39,7 @@ using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using System.Text;
using System.Diagnostics.CodeAnalysis;
using CoreFoundation;
using Foundation;
@ -48,6 +49,8 @@ using Security;
using UIKit;
#endif
#nullable enable
#if !MONOMAC
namespace System.Net.Http {
#else
@ -62,13 +65,13 @@ namespace Foundation {
// useful extensions for the class in order to set it in a header
static class NSHttpCookieExtensions
{
static void AppendSegment(StringBuilder builder, string name, string value)
static void AppendSegment (StringBuilder builder, string name, string? value)
{
if (builder.Length > 0)
builder.Append ("; ");
builder.Append (name);
if (value != null)
if (value is not null)
builder.Append ("=").Append (value);
}
@ -81,16 +84,16 @@ namespace Foundation {
AppendSegment (header, NSHttpCookie.KeyDomain.ToString (), cookie.Domain.ToString ());
AppendSegment (header, NSHttpCookie.KeyVersion.ToString (), cookie.Version.ToString ());
if (cookie.Comment != null)
if (cookie.Comment is not null)
AppendSegment (header, NSHttpCookie.KeyComment.ToString (), cookie.Comment.ToString());
if (cookie.CommentUrl != null)
if (cookie.CommentUrl is not null)
AppendSegment (header, NSHttpCookie.KeyCommentUrl.ToString (), cookie.CommentUrl.ToString());
if (cookie.Properties.ContainsKey (NSHttpCookie.KeyDiscard))
AppendSegment (header, NSHttpCookie.KeyDiscard.ToString (), null);
if (cookie.ExpiresDate != null) {
if (cookie.ExpiresDate is not null) {
// Format according to RFC1123; 'r' uses invariant info (DateTimeFormatInfo.InvariantInfo)
var dateStr = ((DateTime) cookie.ExpiresDate).ToUniversalTime ().ToString("r", CultureInfo.InvariantCulture);
AppendSegment (header, NSHttpCookie.KeyExpires.ToString (), dateStr);
@ -115,7 +118,7 @@ namespace Foundation {
{
private const string SetCookie = "Set-Cookie";
private const string Cookie = "Cookie";
private CookieContainer cookieContainer;
private CookieContainer? cookieContainer;
readonly Dictionary<string, string> headerSeparators = new Dictionary<string, string> {
["User-Agent"] = " ",
["Server"] = " "
@ -126,7 +129,7 @@ namespace Foundation {
readonly object inflightRequestsLock = new object ();
readonly NSUrlSessionConfiguration.SessionConfigurationType sessionType;
#if !MONOMAC && !__WATCHOS__
NSObject notificationToken; // needed to make sure we do not hang if not using a background session
NSObject? notificationToken; // needed to make sure we do not hang if not using a background session
readonly object notificationTokenLock = new object (); // need to make sure that threads do no step on each other with a dispose and a remove inflight data
#endif
@ -148,7 +151,7 @@ namespace Foundation {
[CLSCompliant (false)]
public NSUrlSessionHandler (NSUrlSessionConfiguration configuration)
{
if (configuration == null)
if (configuration is null)
throw new ArgumentNullException (nameof (configuration));
// HACK: we need to store the following because session.Configuration gets a copy of the object and the value gets lost
@ -177,19 +180,19 @@ namespace Foundation {
void AddNotification ()
{
lock (notificationTokenLock) {
if (!bypassBackgroundCheck && sessionType != NSUrlSessionConfiguration.SessionConfigurationType.Background && notificationToken == null)
if (!bypassBackgroundCheck && sessionType != NSUrlSessionConfiguration.SessionConfigurationType.Background && notificationToken is null)
notificationToken = NSNotificationCenter.DefaultCenter.AddObserver (UIApplication.WillResignActiveNotification, BackgroundNotificationCb);
} // lock
}
void RemoveNotification ()
{
NSObject localNotificationToken;
NSObject? localNotificationToken;
lock (notificationTokenLock) {
localNotificationToken = notificationToken;
notificationToken = null;
}
if (localNotificationToken != null)
if (localNotificationToken is not null)
NSNotificationCenter.DefaultCenter.RemoveObserver (localNotificationToken);
}
@ -200,7 +203,7 @@ namespace Foundation {
// iteration. We split the operation in two, get all the diff cancelation sources, then try to cancel each of them
// which will do the correct lock dance. Note that we could be tempted to do a RemoveAll, that will yield the same
// runtime issue, this is dull but safe.
List <TaskCompletionSource<HttpResponseMessage>> sources = null;
List<TaskCompletionSource<HttpResponseMessage>> sources;
lock (inflightRequestsLock) { // just lock when we iterate
sources = new List <TaskCompletionSource<HttpResponseMessage>> (inflightRequests.Count);
foreach (var r in inflightRequests.Values) {
@ -289,9 +292,9 @@ namespace Foundation {
}
}
ICredentials credentials;
ICredentials? credentials;
public ICredentials Credentials {
public ICredentials? Credentials {
get {
return credentials;
}
@ -302,10 +305,10 @@ namespace Foundation {
}
#if !NET
NSUrlSessionHandlerTrustOverrideCallback trustOverride;
NSUrlSessionHandlerTrustOverrideCallback? trustOverride;
[Obsolete ("Use the 'TrustOverrideForUrl' property instead.")]
public NSUrlSessionHandlerTrustOverrideCallback TrustOverride {
public NSUrlSessionHandlerTrustOverrideCallback? TrustOverride {
get {
return trustOverride;
}
@ -316,9 +319,9 @@ namespace Foundation {
}
#endif
NSUrlSessionHandlerTrustOverrideForUrlCallback trustOverrideForUrl;
NSUrlSessionHandlerTrustOverrideForUrlCallback? trustOverrideForUrl;
public NSUrlSessionHandlerTrustOverrideForUrlCallback TrustOverrideForUrl {
public NSUrlSessionHandlerTrustOverrideForUrlCallback? TrustOverrideForUrl {
get {
return trustOverrideForUrl;
}
@ -343,7 +346,7 @@ namespace Foundation {
}
}
public CookieContainer CookieContainer {
public CookieContainer? CookieContainer {
get {
return cookieContainer;
}
@ -355,7 +358,7 @@ namespace Foundation {
public bool UseCookies {
get {
return session.Configuration.HttpCookieStorage != null;
return session.Configuration.HttpCookieStorage is not null;
}
set {
EnsureModifiability ();
@ -368,7 +371,7 @@ namespace Foundation {
// 4. Value is false and cookie container is null -> we do nothing
var oldSession = session;
var configuration = session.Configuration;
if (value && configuration.HttpCookieStorage == null) {
if (value && configuration.HttpCookieStorage is null) {
// create storage because the user wants to use it. Things are not that easy, we have to
// consider the following:
// 1. Default Session -> uses sharedHTTPCookieStorage
@ -376,7 +379,7 @@ namespace Foundation {
// 3. Ephemeral Session -> no allowed. apple does not provide a way to access to the private implementation of the storage class :/
configuration.HttpCookieStorage = NSHttpCookieStorage.SharedStorage;
}
if (!value && configuration.HttpCookieStorage != null) {
if (!value && configuration.HttpCookieStorage is not null) {
// remove storage so that it is not used in any of the requests
configuration.HttpCookieStorage = null;
}
@ -425,8 +428,7 @@ namespace Foundation {
string GetHeaderSeparator (string name)
{
string value;
if (!headerSeparators.TryGetValue (name, out value))
if (!headerSeparators.TryGetValue (name, out var value))
value = ",";
return value;
}
@ -447,8 +449,8 @@ namespace Foundation {
var stream = Stream.Null;
var nativeHeaders = new NSMutableDictionary ();
// set header cookies if needed from the managed cookie container if we do use Cookies
if (session.Configuration.HttpCookieStorage != null) {
var cookies = cookieContainer?.GetCookieHeader (request.RequestUri); // as per docs: An HTTP cookie header, with strings representing Cookie instances delimited by semicolons.
if (session.Configuration.HttpCookieStorage is not null) {
var cookies = cookieContainer?.GetCookieHeader (request.RequestUri!); // as per docs: An HTTP cookie header, with strings representing Cookie instances delimited by semicolons.
if (!string.IsNullOrEmpty (cookies)) {
var cookiePtr = NSString.CreateNative (Cookie);
var cookiesPtr = NSString.CreateNative (cookies);
@ -460,7 +462,7 @@ namespace Foundation {
AddManagedHeaders (nativeHeaders, request.Headers);
if (request.Content != null) {
if (request.Content is not null) {
stream = await request.Content.ReadAsStreamAsync ().ConfigureAwait (false);
AddManagedHeaders (nativeHeaders, request.Content.Headers);
}
@ -469,13 +471,13 @@ namespace Foundation {
AllowsCellularAccess = allowsCellularAccess,
CachePolicy = DisableCaching ? NSUrlRequestCachePolicy.ReloadIgnoringCacheData : NSUrlRequestCachePolicy.UseProtocolCachePolicy,
HttpMethod = request.Method.ToString ().ToUpperInvariant (),
Url = NSUrl.FromString (request.RequestUri.AbsoluteUri),
Url = NSUrl.FromString (request.RequestUri!.AbsoluteUri),
Headers = nativeHeaders,
};
if (stream != Stream.Null) {
// HttpContent.TryComputeLength is `protected internal` :-( but it's indirectly called by headers
var length = request.Content.Headers.ContentLength;
var length = request.Content?.Headers?.ContentLength;
if (length.HasValue && (length <= MaxInputInMemory))
nsrequest.Body = NSData.FromStream (stream);
else
@ -494,21 +496,14 @@ namespace Foundation {
var nsrequest = await CreateRequest (request).ConfigureAwait(false);
var dataTask = session.CreateDataTask (nsrequest);
var tcs = new TaskCompletionSource<HttpResponseMessage> ();
var inflightData = new InflightData (request.RequestUri?.AbsoluteUri!, cancellationToken, request);
lock (inflightRequestsLock) {
#if !MONOMAC && !__WATCHOS__
// Add the notification whenever needed
AddNotification ();
#endif
inflightRequests.Add (dataTask, new InflightData {
RequestUrl = request.RequestUri.AbsoluteUri,
CompletionSource = tcs,
CancellationToken = cancellationToken,
CancellationTokenSource = new CancellationTokenSource (),
Stream = new NSUrlSessionDataTaskStream (),
Request = request
});
inflightRequests.Add (dataTask, inflightData);
}
if (dataTask.State == NSUrlSessionTaskState.Suspended)
@ -528,10 +523,10 @@ namespace Foundation {
// execution a threads cancels it.
cancellationToken.Register (() => {
RemoveInflightData (dataTask);
tcs.TrySetCanceled ();
inflightData.CompletionSource.TrySetCanceled ();
});
return await tcs.Task.ConfigureAwait (false);
return await inflightData.CompletionSource.Task.ConfigureAwait (false);
}
#if NET
@ -626,7 +621,7 @@ namespace Foundation {
sessionHandler = handler;
}
InflightData GetInflightData (NSUrlSessionTask task)
InflightData? GetInflightData (NSUrlSessionTask task)
{
var inflight = default (InflightData);
@ -657,7 +652,7 @@ namespace Foundation {
void UpdateManagedCookieContainer (NSUrl url, NSHttpCookie[] cookies)
{
var uri = new Uri (url.AbsoluteString);
if (sessionHandler.cookieContainer != null && cookies.Length > 0)
if (sessionHandler.cookieContainer is not null && cookies.Length > 0)
lock (sessionHandler.inflightRequestsLock) { // ensure we lock when writing to the collection
var cookiesContents = new string [cookies.Length];
for (var index = 0; index < cookies.Length; index++)
@ -671,7 +666,7 @@ namespace Foundation {
{
var inflight = GetInflightData (dataTask);
if (inflight == null)
if (inflight is null)
return;
try {
@ -698,7 +693,7 @@ namespace Foundation {
foreach (var v in urlResponse.AllHeaderFields) {
// NB: Cocoa trolling us so hard by giving us back dummy dictionary entries
if (v.Key == null || v.Value == null) continue;
if (v.Key is null || v.Value is null) continue;
// NSUrlSession tries to be smart with cookies, we will not use the raw value but the ones provided by the cookie storage
if (v.Key.ToString () == SetCookie) continue;
@ -709,7 +704,7 @@ namespace Foundation {
// it might be confusing that we are not using the managed CookieStore here, this is ONLY for those cookies that have been retrieved from
// the server via a Set-Cookie header, the managed container does not know a thing about this and apple is storing them in the native
// cookie container. Once we have the cookies from the response, we need to update the managed cookie container
if (session.Configuration.HttpCookieStorage != null) {
if (session.Configuration.HttpCookieStorage is not null) {
var cookies = session.Configuration.HttpCookieStorage.CookiesForUrl (response.Url);
UpdateManagedCookieContainer (response.Url, cookies);
for (var index = 0; index < cookies.Length; index++) {
@ -740,7 +735,7 @@ namespace Foundation {
{
var inflight = GetInflightData (dataTask);
if (inflight == null)
if (inflight is null)
return;
inflight.Stream.Add (data);
@ -748,23 +743,23 @@ namespace Foundation {
}
[Preserve (Conditional = true)]
public override void DidCompleteWithError (NSUrlSession session, NSUrlSessionTask task, NSError error)
public override void DidCompleteWithError (NSUrlSession session, NSUrlSessionTask task, NSError? error)
{
var inflight = GetInflightData (task);
var serverError = task.Error;
// this can happen if the HTTP request times out and it is removed as part of the cancellation process
if (inflight != null) {
if (inflight is not null) {
// set the stream as finished
inflight.Stream.TrySetReceivedAllData ();
// send the error or send the response back
if (error != null || serverError != null) {
if (error is not null || serverError is not null) {
// got an error, cancel the stream operatios before we do anything
inflight.CancellationTokenSource.Cancel ();
inflight.Errored = true;
var exc = inflight.Exception ?? createExceptionForNSError (error ?? serverError); // client errors wont happen if we get server errors
var exc = inflight.Exception ?? createExceptionForNSError (error ?? serverError!); // client errors wont happen if we get server errors
inflight.CompletionSource.TrySetException (exc);
inflight.Stream.TrySetException (exc);
} else {
@ -793,20 +788,20 @@ namespace Foundation {
inflight.ResponseSent = true;
// EVIL HACK: having TrySetResult inline was blocking the request from completing
Task.Run (() => inflight.CompletionSource.TrySetResult (httpResponse));
Task.Run (() => inflight.CompletionSource.TrySetResult (httpResponse!));
}
}
[Preserve (Conditional = true)]
public override void WillCacheResponse (NSUrlSession session, NSUrlSessionDataTask dataTask, NSCachedUrlResponse proposedResponse, Action<NSCachedUrlResponse> completionHandler)
{
completionHandler (sessionHandler.DisableCaching ? null : proposedResponse);
completionHandler (sessionHandler.DisableCaching ? null! : proposedResponse);
}
[Preserve (Conditional = true)]
public override void WillPerformHttpRedirection (NSUrlSession session, NSUrlSessionTask task, NSHttpUrlResponse response, NSUrlRequest newRequest, Action<NSUrlRequest> completionHandler)
{
completionHandler (sessionHandler.AllowAutoRedirect ? newRequest : null);
completionHandler (sessionHandler.AllowAutoRedirect ? newRequest : null!);
}
[Preserve (Conditional = true)]
@ -814,7 +809,7 @@ namespace Foundation {
{
var inflight = GetInflightData (task);
if (inflight == null)
if (inflight is null)
return;
// ToCToU for the callback
@ -825,7 +820,7 @@ namespace Foundation {
#if NET
var hasCallBack = trustCallbackForUrl is not null;
#else
var hasCallBack = trustCallback != null || trustCallbackForUrl != null;
var hasCallBack = trustCallback is not null || trustCallbackForUrl is not null;
#endif
if (hasCallBack && challenge.ProtectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodServerTrust) {
#if NET
@ -847,7 +842,7 @@ namespace Foundation {
lock (inflight.Lock) {
inflight.Exception = new HttpRequestException ("An error occurred while sending the request.", new WebException ("Error: TrustFailure"));
}
completionHandler (NSUrlSessionAuthChallengeDisposition.CancelAuthenticationChallenge, null);
completionHandler (NSUrlSessionAuthChallengeDisposition.CancelAuthenticationChallenge, null!);
}
return;
}
@ -865,15 +860,15 @@ namespace Foundation {
// header, it means that we do not have the correct credentials, in any other case just do what it is expected.
if (challenge.PreviousFailureCount == 0) {
var authHeader = inflight.Request?.Headers?.Authorization;
var authHeader = inflight.Request.Headers?.Authorization;
if (!(string.IsNullOrEmpty (authHeader?.Scheme) && string.IsNullOrEmpty (authHeader?.Parameter))) {
completionHandler (NSUrlSessionAuthChallengeDisposition.RejectProtectionSpace, null);
completionHandler (NSUrlSessionAuthChallengeDisposition.RejectProtectionSpace, null!);
return;
}
}
if (sessionHandler.Credentials != null && TryGetAuthenticationType (challenge.ProtectionSpace, out string authType)) {
NetworkCredential credentialsToUse = null;
if (sessionHandler.Credentials is not null && TryGetAuthenticationType (challenge.ProtectionSpace, out var authType)) {
NetworkCredential? credentialsToUse = null;
if (authType != RejectProtectionSpaceAuthType) {
// interesting situation, when we use a credential that we created that is empty, we are not getting the RejectProtectionSpaceAuthType,
// nevertheless, we need to check is not the first challenge we will continue trusting the
@ -890,20 +885,20 @@ namespace Foundation {
// }
// do remember that we ALWAYS get a challenge, so the failure count has to be 1 or more for this check, 1 would be the first time
var nsurlRespose = challenge.FailureResponse as NSHttpUrlResponse;
var responseIsUnauthorized = (nsurlRespose == null) ? false : nsurlRespose.StatusCode == (int) HttpStatusCode.Unauthorized && challenge.PreviousFailureCount > 0;
var responseIsUnauthorized = (nsurlRespose is null) ? false : nsurlRespose.StatusCode == (int) HttpStatusCode.Unauthorized && challenge.PreviousFailureCount > 0;
if (!responseIsUnauthorized) {
var uri = inflight.Request.RequestUri;
var uri = inflight.Request.RequestUri!;
credentialsToUse = sessionHandler.Credentials.GetCredential (uri, authType);
}
}
if (credentialsToUse != null) {
if (credentialsToUse is not null) {
var credential = new NSUrlCredential (credentialsToUse.UserName, credentialsToUse.Password, NSUrlCredentialPersistence.ForSession);
completionHandler (NSUrlSessionAuthChallengeDisposition.UseCredential, credential);
} else {
// Rejecting the challenge allows the next authentication method in the request to be delivered to
// the DidReceiveChallenge method. Another authentication method may have credentials available.
completionHandler (NSUrlSessionAuthChallengeDisposition.RejectProtectionSpace, null);
completionHandler (NSUrlSessionAuthChallengeDisposition.RejectProtectionSpace, null!);
}
} else {
completionHandler (NSUrlSessionAuthChallengeDisposition.PerformDefaultHandling, challenge.ProposedCredential);
@ -912,7 +907,7 @@ namespace Foundation {
static readonly string RejectProtectionSpaceAuthType = "reject";
static bool TryGetAuthenticationType (NSUrlProtectionSpace protectionSpace, out string authenticationType)
static bool TryGetAuthenticationType (NSUrlProtectionSpace protectionSpace, [NotNullWhen (true)] out string? authenticationType)
{
if (protectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodNTLM) {
authenticationType = "NTLM";
@ -938,20 +933,27 @@ namespace Foundation {
public readonly object Lock = new object ();
public string RequestUrl { get; set; }
public TaskCompletionSource<HttpResponseMessage> CompletionSource { get; set; }
public TaskCompletionSource<HttpResponseMessage> CompletionSource { get; } = new TaskCompletionSource<HttpResponseMessage> ();
public CancellationToken CancellationToken { get; set; }
public CancellationTokenSource CancellationTokenSource { get; set; }
public NSUrlSessionDataTaskStream Stream { get; set; }
public CancellationTokenSource CancellationTokenSource { get; } = new CancellationTokenSource ();
public NSUrlSessionDataTaskStream Stream { get; } = new NSUrlSessionDataTaskStream ();
public HttpRequestMessage Request { get; set; }
public HttpResponseMessage Response { get; set; }
public HttpResponseMessage? Response { get; set; }
public Exception Exception { get; set; }
public Exception? Exception { get; set; }
public bool ResponseSent { get; set; }
public bool Errored { get; set; }
public bool Disposed { get; set; }
public bool Completed { get; set; }
public bool Done { get { return Errored || Disposed || Completed || CancellationToken.IsCancellationRequested; } }
public InflightData (string requestUrl, CancellationToken cancellationToken, HttpRequestMessage request)
{
RequestUrl = requestUrl;
CancellationToken = cancellationToken;
Request = request;
}
public void Dispose()
{
Dispose (true);
@ -962,10 +964,7 @@ namespace Foundation {
protected virtual void Dispose (bool disposing)
{
if (disposing) {
if (CancellationTokenSource != null) {
CancellationTokenSource.Dispose ();
CancellationTokenSource = null;
}
CancellationTokenSource.Dispose ();
}
}
@ -973,7 +972,7 @@ namespace Foundation {
class NSUrlSessionDataTaskStreamContent : MonoStreamContent
{
Action disposed;
Action? disposed;
public NSUrlSessionDataTaskStreamContent (NSUrlSessionDataTaskStream source, Action onDisposed, CancellationToken token) : base (source, token)
{
@ -1015,7 +1014,7 @@ namespace Foundation {
public MonoStreamContent (Stream content, int bufferSize)
{
if (content == null)
if (content is null)
throw new ArgumentNullException ("content");
if (bufferSize <= 0)
@ -1055,7 +1054,7 @@ namespace Foundation {
base.Dispose (disposing);
}
protected override Task SerializeToStreamAsync (Stream stream, TransportContext context)
protected override Task SerializeToStreamAsync (Stream stream, TransportContext? context)
{
if (contentCopied) {
if (!content.CanSeek) {
@ -1093,10 +1092,10 @@ namespace Foundation {
long length;
bool receivedAllData;
Exception exc;
Exception? exc;
NSData current;
Stream currentStream;
NSData? current;
Stream? currentStream;
public NSUrlSessionDataTaskStream ()
{
@ -1124,7 +1123,7 @@ namespace Foundation {
void ThrowIfNeeded (CancellationToken cancellationToken)
{
if (exc != null)
if (exc is not null)
throw exc;
cancellationToken.ThrowIfCancellationRequested ();
@ -1140,12 +1139,12 @@ namespace Foundation {
// try to throw on enter
ThrowIfNeeded (cancellationToken);
while (current == null) {
while (current is null) {
lock (dataLock) {
if (data.Count == 0 && receivedAllData && position == length)
return 0;
if (data.Count > 0 && current == null) {
if (data.Count > 0 && current is null) {
current = data.Peek ();
currentStream = current.AsStream ();
break;
@ -1164,7 +1163,7 @@ namespace Foundation {
// try to throw again before read
ThrowIfNeeded (cancellationToken);
var d = currentStream;
var d = currentStream!;
var bufferCount = Math.Min (count, (int)(d.Length - d.Position));
var bytesRead = await d.ReadAsync (buffer, offset, bufferCount, cancellationToken).ConfigureAwait (false);
@ -1287,12 +1286,12 @@ namespace Foundation {
}
// NSInvalidArgumentException Reason: *** -propertyForKey: only defined for abstract class. Define -[System_Net_Http_NSUrlSessionHandler_WrappedNSInputStream propertyForKey:]!
protected override NSObject GetProperty (NSString key)
protected override NSObject? GetProperty (NSString key)
{
return null;
}
protected override bool SetProperty (NSObject property, NSString key)
protected override bool SetProperty (NSObject? property, NSString key)
{
return false;
}

Просмотреть файл

@ -7046,10 +7046,10 @@ namespace Foundation
#if !NET
[Obsolete ("Use the overload with a 'INSUrlSessionDelegate' parameter.")]
[Static, Wrap ("FromWeakConfiguration (configuration, sessionDelegate, delegateQueue);")]
NSUrlSession FromConfiguration (NSUrlSessionConfiguration configuration, NSUrlSessionDelegate sessionDelegate, NSOperationQueue delegateQueue);
NSUrlSession FromConfiguration (NSUrlSessionConfiguration configuration, NSUrlSessionDelegate sessionDelegate, [NullAllowed] NSOperationQueue delegateQueue);
#endif
[Static, Wrap ("FromWeakConfiguration (configuration, (NSObject) sessionDelegate, delegateQueue);")]
NSUrlSession FromConfiguration (NSUrlSessionConfiguration configuration, INSUrlSessionDelegate sessionDelegate, NSOperationQueue delegateQueue);
NSUrlSession FromConfiguration (NSUrlSessionConfiguration configuration, INSUrlSessionDelegate sessionDelegate, [NullAllowed] NSOperationQueue delegateQueue);
[Export ("delegateQueue", ArgumentSemantic.Retain)]
NSOperationQueue DelegateQueue { get; }
@ -7608,7 +7608,7 @@ namespace Foundation
void DidSendBodyData (NSUrlSession session, NSUrlSessionTask task, long bytesSent, long totalBytesSent, long totalBytesExpectedToSend);
[Export ("URLSession:task:didCompleteWithError:")]
void DidCompleteWithError (NSUrlSession session, NSUrlSessionTask task, NSError error);
void DidCompleteWithError (NSUrlSession session, NSUrlSessionTask task, [NullAllowed] NSError error);
[Watch (3,0)][TV (10,0)][Mac (10,12)][iOS (10,0)]
[Export ("URLSession:task:didFinishCollectingMetrics:")]
@ -8195,6 +8195,7 @@ namespace Foundation
#if NET
[Abstract]
#endif
[return: NullAllowed]
[Protected]
[Export ("propertyForKey:")]
NSObject GetProperty (NSString key);
@ -8683,6 +8684,7 @@ namespace Foundation
NSInputStream FromUrl (NSUrl url);
#if NET
[return: NullAllowed]
[Protected]
[Export ("propertyForKey:"), Override]
NSObject GetProperty (NSString key);
@ -9581,6 +9583,7 @@ namespace Foundation
NSOutputStream CreateFile (string path, bool shouldAppend);
#if NET
[return: NullAllowed]
[Protected]
[Export ("propertyForKey:"), Override]
NSObject GetProperty (NSString key);

Просмотреть файл

@ -1061,7 +1061,6 @@
!missing-null-allowed! 'Foundation.NSObject Foundation.NSPropertyListSerialization::PropertyListWithStream(Foundation.NSInputStream,Foundation.NSPropertyListReadOptions,Foundation.NSPropertyListFormat&,Foundation.NSError&)' is missing an [NullAllowed] on return type
!missing-null-allowed! 'Foundation.NSObject Foundation.NSSet::get_AnyObject()' is missing an [NullAllowed] on return type
!missing-null-allowed! 'Foundation.NSObject Foundation.NSSet::LookupMember(Foundation.NSObject)' is missing an [NullAllowed] on return type
!missing-null-allowed! 'Foundation.NSObject Foundation.NSStream::GetProperty(Foundation.NSString)' is missing an [NullAllowed] on return type
!missing-null-allowed! 'Foundation.NSObject Foundation.NSTimer::get_UserInfo()' is missing an [NullAllowed] on return type
!missing-null-allowed! 'Foundation.NSObject Foundation.NSUrlProtocol::GetProperty(System.String,Foundation.NSUrlRequest)' is missing an [NullAllowed] on return type
!missing-null-allowed! 'Foundation.NSObject Foundation.NSUserDefaults::ObjectForKey(System.String)' is missing an [NullAllowed] on return type

Просмотреть файл

@ -1073,7 +1073,6 @@
!missing-null-allowed! 'Foundation.NSObject Foundation.NSPropertyListSerialization::PropertyListWithStream(Foundation.NSInputStream,Foundation.NSPropertyListReadOptions,Foundation.NSPropertyListFormat&,Foundation.NSError&)' is missing an [NullAllowed] on return type
!missing-null-allowed! 'Foundation.NSObject Foundation.NSSet::get_AnyObject()' is missing an [NullAllowed] on return type
!missing-null-allowed! 'Foundation.NSObject Foundation.NSSet::LookupMember(Foundation.NSObject)' is missing an [NullAllowed] on return type
!missing-null-allowed! 'Foundation.NSObject Foundation.NSStream::GetProperty(Foundation.NSString)' is missing an [NullAllowed] on return type
!missing-null-allowed! 'Foundation.NSObject Foundation.NSTimer::get_UserInfo()' is missing an [NullAllowed] on return type
!missing-null-allowed! 'Foundation.NSObject Foundation.NSUrlProtocol::GetProperty(System.String,Foundation.NSUrlRequest)' is missing an [NullAllowed] on return type
!missing-null-allowed! 'Foundation.NSObject Foundation.NSUserDefaults::ObjectForKey(System.String)' is missing an [NullAllowed] on return type