blob: a9bbdc5f104c67e1a207aad8c8431339273309e6 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// TODO(a14n): remove this import once Flutter 3.1 or later reaches stable (including flutter/flutter#104231)
// ignore: unnecessary_import
import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import '../common/instance_manager.dart';
import '../common/weak_reference_utils.dart';
import 'foundation_api_impls.dart';
/// The values that can be returned in a change map.
///
/// Wraps [NSKeyValueObservingOptions](https://developer.apple.com/documentation/foundation/nskeyvalueobservingoptions?language=objc).
enum NSKeyValueObservingOptions {
/// Indicates that the change map should provide the new attribute value, if applicable.
///
/// See https://developer.apple.com/documentation/foundation/nskeyvalueobservingoptions/nskeyvalueobservingoptionnew?language=objc.
newValue,
/// Indicates that the change map should contain the old attribute value, if applicable.
///
/// See https://developer.apple.com/documentation/foundation/nskeyvalueobservingoptions/nskeyvalueobservingoptionold?language=objc.
oldValue,
/// Indicates a notification should be sent to the observer immediately.
///
/// See https://developer.apple.com/documentation/foundation/nskeyvalueobservingoptions/nskeyvalueobservingoptioninitial?language=objc.
initialValue,
/// Whether separate notifications should be sent to the observer before and after each change.
///
/// See https://developer.apple.com/documentation/foundation/nskeyvalueobservingoptions/nskeyvalueobservingoptionprior?language=objc.
priorNotification,
}
/// The kinds of changes that can be observed.
///
/// Wraps [NSKeyValueChange](https://developer.apple.com/documentation/foundation/nskeyvaluechange?language=objc).
enum NSKeyValueChange {
/// Indicates that the value of the observed key path was set to a new value.
///
/// See https://developer.apple.com/documentation/foundation/nskeyvaluechange/nskeyvaluechangesetting?language=objc.
setting,
/// Indicates that an object has been inserted into the to-many relationship that is being observed.
///
/// See https://developer.apple.com/documentation/foundation/nskeyvaluechange/nskeyvaluechangeinsertion?language=objc.
insertion,
/// Indicates that an object has been removed from the to-many relationship that is being observed.
///
/// See https://developer.apple.com/documentation/foundation/nskeyvaluechange/nskeyvaluechangeremoval?language=objc.
removal,
/// Indicates that an object has been replaced in the to-many relationship that is being observed.
///
/// See https://developer.apple.com/documentation/foundation/nskeyvaluechange/nskeyvaluechangereplacement?language=objc.
replacement,
}
/// The keys that can appear in the change map.
///
/// Wraps [NSKeyValueChangeKey](https://developer.apple.com/documentation/foundation/nskeyvaluechangekey?language=objc).
enum NSKeyValueChangeKey {
/// Indicates changes made in a collection.
///
/// See https://developer.apple.com/documentation/foundation/nskeyvaluechangeindexeskey?language=objc.
indexes,
/// Indicates what sort of change has occurred.
///
/// See https://developer.apple.com/documentation/foundation/nskeyvaluechangekindkey?language=objc.
kind,
/// Indicates the new value for the attribute.
///
/// See https://developer.apple.com/documentation/foundation/nskeyvaluechangenewkey?language=objc.
newValue,
/// Indicates a notification is sent prior to a change.
///
/// See https://developer.apple.com/documentation/foundation/nskeyvaluechangenotificationispriorkey?language=objc.
notificationIsPrior,
/// Indicates the value of this key is the value before the attribute was changed.
///
/// See https://developer.apple.com/documentation/foundation/nskeyvaluechangeoldkey?language=objc.
oldValue,
}
/// The supported keys in a cookie attributes dictionary.
///
/// Wraps [NSHTTPCookiePropertyKey](https://developer.apple.com/documentation/foundation/nshttpcookiepropertykey).
enum NSHttpCookiePropertyKey {
/// A String object containing the comment for the cookie.
///
/// See https://developer.apple.com/documentation/foundation/nshttpcookiecomment.
comment,
/// A String object containing the comment URL for the cookie.
///
/// See https://developer.apple.com/documentation/foundation/nshttpcookiecommenturl.
commentUrl,
/// A String object stating whether the cookie should be discarded at the end of the session.
///
/// See https://developer.apple.com/documentation/foundation/nshttpcookiediscard.
discard,
/// A String object specifying the expiration date for the cookie.
///
/// See https://developer.apple.com/documentation/foundation/nshttpcookiedomain.
domain,
/// A String object specifying the expiration date for the cookie.
///
/// See https://developer.apple.com/documentation/foundation/nshttpcookieexpires.
expires,
/// A String object containing an integer value stating how long in seconds the cookie should be kept, at most.
///
/// See https://developer.apple.com/documentation/foundation/nshttpcookiemaximumage.
maximumAge,
/// A String object containing the name of the cookie (required).
///
/// See https://developer.apple.com/documentation/foundation/nshttpcookiename.
name,
/// A String object containing the URL that set this cookie.
///
/// See https://developer.apple.com/documentation/foundation/nshttpcookieoriginurl.
originUrl,
/// A String object containing the path for the cookie.
///
/// See https://developer.apple.com/documentation/foundation/nshttpcookiepath.
path,
/// A String object containing comma-separated integer values specifying the ports for the cookie.
///
/// See https://developer.apple.com/documentation/foundation/nshttpcookieport.
port,
/// A String indicating the same-site policy for the cookie.
///
/// This is only supported on iOS version 13+. This value will be ignored on
/// versions < 13.
///
/// See https://developer.apple.com/documentation/foundation/nshttpcookiesamesitepolicy.
sameSitePolicy,
/// A String object indicating that the cookie should be transmitted only over secure channels.
///
/// See https://developer.apple.com/documentation/foundation/nshttpcookiesecure.
secure,
/// A String object containing the value of the cookie.
///
/// See https://developer.apple.com/documentation/foundation/nshttpcookievalue.
value,
/// A String object that specifies the version of the cookie.
///
/// See https://developer.apple.com/documentation/foundation/nshttpcookieversion.
version,
}
/// A URL load request that is independent of protocol or URL scheme.
///
/// Wraps [NSUrlRequest](https://developer.apple.com/documentation/foundation/nsurlrequest?language=objc).
@immutable
class NSUrlRequest {
/// Constructs an [NSUrlRequest].
const NSUrlRequest({
required this.url,
this.httpMethod,
this.httpBody,
this.allHttpHeaderFields = const <String, String>{},
});
/// The URL being requested.
final String url;
/// The HTTP request method.
///
/// The default HTTP method is “GET”.
final String? httpMethod;
/// Data sent as the message body of a request, as in an HTTP POST request.
final Uint8List? httpBody;
/// All of the HTTP header fields for a request.
final Map<String, String> allHttpHeaderFields;
}
/// Information about an error condition.
///
/// Wraps [NSError](https://developer.apple.com/documentation/foundation/nserror?language=objc).
@immutable
class NSError {
/// Constructs an [NSError].
const NSError({
required this.code,
required this.domain,
required this.localizedDescription,
});
/// The error code.
///
/// Note that errors are domain-specific.
final int code;
/// A string containing the error domain.
final String domain;
/// A string containing the localized description of the error.
final String localizedDescription;
}
/// A representation of an HTTP cookie.
///
/// Wraps [NSHTTPCookie](https://developer.apple.com/documentation/foundation/nshttpcookie).
@immutable
class NSHttpCookie {
/// Initializes an HTTP cookie object using the provided properties.
const NSHttpCookie.withProperties(this.properties);
/// Properties of the new cookie object.
final Map<NSHttpCookiePropertyKey, Object> properties;
}
/// An object that represents the location of a resource, such as an item on a
/// remote server or the path to a local file.
///
/// See https://developer.apple.com/documentation/foundation/nsurl?language=objc.
class NSUrl extends NSObject {
/// Instantiates a [NSUrl] without creating and attaching to an instance
/// of the associated native class.
///
/// This should only be used outside of tests by subclasses created by this
/// library or to create a copy for an [InstanceManager].
@protected
NSUrl.detached({super.binaryMessenger, super.instanceManager})
: _nsUrlHostApi = NSUrlHostApiImpl(
binaryMessenger: binaryMessenger,
instanceManager: instanceManager,
),
super.detached();
final NSUrlHostApiImpl _nsUrlHostApi;
/// The URL string for the receiver as an absolute URL. (read-only)
///
/// Represents [NSURL.absoluteString](https://developer.apple.com/documentation/foundation/nsurl/1409868-absolutestring?language=objc).
Future<String?> getAbsoluteString() {
return _nsUrlHostApi.getAbsoluteStringFromInstances(this);
}
@override
NSObject copy() {
return NSUrl.detached(
binaryMessenger: _nsUrlHostApi.binaryMessenger,
instanceManager: _nsUrlHostApi.instanceManager,
);
}
}
/// The root class of most Objective-C class hierarchies.
@immutable
class NSObject with Copyable {
/// Constructs a [NSObject] without creating the associated
/// Objective-C object.
///
/// This should only be used by subclasses created by this library or to
/// create copies.
NSObject.detached({
this.observeValue,
BinaryMessenger? binaryMessenger,
InstanceManager? instanceManager,
}) : _api = NSObjectHostApiImpl(
binaryMessenger: binaryMessenger,
instanceManager: instanceManager,
) {
// Ensures FlutterApis for the Foundation library are set up.
FoundationFlutterApis.instance.ensureSetUp();
}
/// Release the reference to the Objective-C object.
static void dispose(NSObject instance) {
instance._api.instanceManager.removeWeakReference(instance);
}
/// Global instance of [InstanceManager].
static final InstanceManager globalInstanceManager =
InstanceManager(onWeakReferenceRemoved: (int instanceId) {
NSObjectHostApiImpl().dispose(instanceId);
});
final NSObjectHostApiImpl _api;
/// Informs the observing object when the value at the specified key path has
/// changed.
///
/// {@template webview_flutter_wkwebview.foundation.callbacks}
/// For the associated Objective-C object to be automatically garbage
/// collected, it is required that this Function doesn't contain a strong
/// reference to the encapsulating class instance. Consider using
/// `WeakReference` when referencing an object not received as a parameter.
/// Otherwise, use [NSObject.dispose] to release the associated Objective-C
/// object manually.
///
/// See [withWeakReferenceTo].
/// {@endtemplate}
final void Function(
String keyPath,
NSObject object,
Map<NSKeyValueChangeKey, Object?> change,
)? observeValue;
/// Registers the observer object to receive KVO notifications.
Future<void> addObserver(
NSObject observer, {
required String keyPath,
required Set<NSKeyValueObservingOptions> options,
}) {
assert(options.isNotEmpty);
return _api.addObserverForInstances(
this,
observer,
keyPath,
options,
);
}
/// Stops the observer object from receiving change notifications for the property.
Future<void> removeObserver(NSObject observer, {required String keyPath}) {
return _api.removeObserverForInstances(this, observer, keyPath);
}
@override
NSObject copy() {
return NSObject.detached(
observeValue: observeValue,
binaryMessenger: _api.binaryMessenger,
instanceManager: _api.instanceManager,
);
}
}