Open Therzok opened 2 years ago
Interesting enough, if you look at the online documentation:
Those are not deprecated, just the non-mutable ones.
And sharpie seems to agree with me:
% sharpie query iphoneos15.4-arm64.pch -n dictionaryWithContentsOfURL: -b
// @interface NSDeprecated (NSDictionary)
[Category]
[BaseType (typeof(NSDictionary))]
interface NSDictionary_NSDeprecated
{
// +(NSDictionary<KeyType,ObjectType> * _Nullable)dictionaryWithContentsOfURL:(NSURL * _Nonnull)url __attribute__((availability(macos, introduced=10.0, deprecated=100000))) __attribute__((availability(ios, introduced=2.0, deprecated=100000))) __attribute__((availability(watchos, introduced=2.0, deprecated=100000))) __attribute__((availability(tvos, introduced=9.0, deprecated=100000)));
[Introduced (PlatformName.MacOSX, 10, 0)]
[Deprecated (PlatformName.MacOSX, 100000, 0)]
[Introduced (PlatformName.iOS, 2, 0)]
[Deprecated (PlatformName.iOS, 100000, 0)]
[Introduced (PlatformName.WatchOS, 2, 0)]
[Deprecated (PlatformName.WatchOS, 100000, 0)]
[Introduced (PlatformName.TvOS, 9, 0)]
[Deprecated (PlatformName.TvOS, 100000, 0)]
[Static]
[Export ("dictionaryWithContentsOfURL:")]
[return: NullAllowed]
NSDictionary<NSObject, NSObject> DictionaryWithContentsOfURL (NSUrl url);
}
// @interface NSMutableDictionaryCreation (NSMutableDictionary)
[Category]
[BaseType (typeof(NSMutableDictionary))]
interface NSMutableDictionary_NSMutableDictionaryCreation
{
// +(NSMutableDictionary<KeyType,ObjectType> * _Nullable)dictionaryWithContentsOfURL:(NSURL * _Nonnull)url;
[Static]
[Export ("dictionaryWithContentsOfURL:")]
[return: NullAllowed]
NSMutableDictionary<NSObject, NSObject> DictionaryWithContentsOfURL (NSUrl url);
}
So by default @Therzok I'm going to write this off as "Apple being Apple" and not a bug in the SDK.
If I missed something, please reopen.
@chamons The non-error variants are being recommended, which are deprecated in native. Native recommendations are to use the out error
versions.
Is that documented somewhere?
We tend to bind the Apple frameworks exactly as documented/header shows.
I'm not exactly following what your suggest we do here.
Taken literally from the headers:
/* These methods are deprecated, and will be marked with API_DEPRECATED in a subsequent release. Use the variants that use errors instead. */
+ (nullable NSDictionary<KeyType, ObjectType> *)dictionaryWithContentsOfFile:(NSString *)path API_DEPRECATED_WITH_REPLACEMENT("dictionaryWithContentsOfURL:error:", macos(10.0, API_TO_BE_DEPRECATED), ios(2.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED));
+ (nullable NSDictionary<KeyType, ObjectType> *)dictionaryWithContentsOfURL:(NSURL *)url API_DEPRECATED_WITH_REPLACEMENT("dictionaryWithContentsOfURL:error:", macos(10.0, API_TO_BE_DEPRECATED), ios(2.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED));
- (nullable NSDictionary<KeyType, ObjectType> *)initWithContentsOfFile:(NSString *)path API_DEPRECATED_WITH_REPLACEMENT("initWithContentsOfURL:error:", macos(10.0, API_TO_BE_DEPRECATED), ios(2.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED));
- (nullable NSDictionary<KeyType, ObjectType> *)initWithContentsOfURL:(NSURL *)url API_DEPRECATED_WITH_REPLACEMENT("initWithContentsOfURL:error:", macos(10.0, API_TO_BE_DEPRECATED), ios(2.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED));
Basically, NSDictionary.FromUrl(string)
is suggesting new NSMutableDictionary(string)
as a replacement, but it should be NSDictionary.FromUrl(string, out NSError error)
.
Edit: The ask is for NSDictionary. I also mentioned NSMutableDictionary
in the issue description just because I spotted the inconsistency.
Or, the former API can be undeprecated, and the NSError can be converted to throw an NSErrorException
automatically. But I think the previous fix is more in line with the APIs in Xamarin.Mac.
Ok, it's only in the headers and no API_DEPRECATED yet. I haven't seen Apple do that in awhile.
Wait, those are actually on NSDictionary, not the mutable one.
@interface NSDictionary<KeyType, ObjectType> (NSDeprecated)
/// This method is unsafe because it could potentially cause buffer overruns. You should use -getObjects:andKeys:count:
- (void)getObjects:(ObjectType _Nonnull __unsafe_unretained [_Nullable])objects andKeys:(KeyType _Nonnull __unsafe_unretained [_Nullable])keys NS_SWIFT_UNAVAILABLE("Use 'allKeys' and/or 'allValues' instead") API_DEPRECATED("Use -getObjects:andKeys:count: instead", macos(10.0, 10.13), ios(2.0, 11.0), watchos(2.0, 4.0), tvos(9.0, 11.0));
/* These methods are deprecated, and will be marked with API_DEPRECATED in a subsequent release. Use the variants that use errors instead. */
+ (nullable NSDictionary<KeyType, ObjectType> *)dictionaryWithContentsOfFile:(NSString *)path API_DEPRECATED_WITH_REPLACEMENT("dictionaryWithContentsOfURL:error:", macos(10.0, API_TO_BE_DEPRECATED), ios(2.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED));
+ (nullable NSDictionary<KeyType, ObjectType> *)dictionaryWithContentsOfURL:(NSURL *)url API_DEPRECATED_WITH_REPLACEMENT("dictionaryWithContentsOfURL:error:", macos(10.0, API_TO_BE_DEPRECATED), ios(2.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED));
- (nullable NSDictionary<KeyType, ObjectType> *)initWithContentsOfFile:(NSString *)path API_DEPRECATED_WITH_REPLACEMENT("initWithContentsOfURL:error:", macos(10.0, API_TO_BE_DEPRECATED), ios(2.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED));
- (nullable NSDictionary<KeyType, ObjectType> *)initWithContentsOfURL:(NSURL *)url API_DEPRECATED_WITH_REPLACEMENT("initWithContentsOfURL:error:", macos(10.0, API_TO_BE_DEPRECATED), ios(2.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED));
and the Mutable version does not have anything:
@interface NSMutableDictionary<KeyType, ObjectType> (NSMutableDictionaryCreation)
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
+ (nullable NSMutableDictionary<KeyType, ObjectType> *)dictionaryWithContentsOfFile:(NSString *)path;
+ (nullable NSMutableDictionary<KeyType, ObjectType> *)dictionaryWithContentsOfURL:(NSURL *)url;
- (nullable NSMutableDictionary<KeyType, ObjectType> *)initWithContentsOfFile:(NSString *)path;
- (nullable NSMutableDictionary<KeyType, ObjectType> *)initWithContentsOfURL:(NSURL *)url;
@end
However, there is inheritance there.
We'll have to figure out how we want to proceed, if any (deprecate them now or wait for apple).
Steps to Reproduce
Expected Behavior
NSDictionary.ctor(string)
->Use NSDictionary.FromUrl(NSUrl, out NSError)
NSDictionary.ctor(NSUrl)
->Use NSDictionary.FromUrl(NSUrl, out NSError)
Actual Behavior
NSDictionary.ctor(string)
->Use NSMutableDictionary(string)
NSDictionary.ctor(NSUrl)
->Use NSMutableDictionary(NSUrl)
Environment
dotnet 6.0.201
Notes
Looking at the native headers, I see:
For some reason, the NSMutableDictionary versions are not flagged: