[iOS] Make RTCRtpTransceiver.setCodecPreferences failable and accept nil

Web Spec and C++ version of setCodecPreferences are failable, as they return
an RTCError (in C++) or throw an InvalidModificationError (in Web Spec).
However, current Objective-C version of setCodecPreferences is not failable,
so callers cannot know if the operation succeeded or not.
Also, the current Objective-C version does not accept nil, which is not
spec-compliant. (Web Spec says if codecs is an empty list, set
transceiver.PreferredCodecs to codecs and abort these steps.)

Bug: webrtc:42226103, webrtc:42226230
Change-Id: Ib90f3e5b45fc959eeb92f623cf50efcb458a7478
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/352400
Reviewed-by: Kári Helgason <kthelgason@webrtc.org>
Commit-Queue: Kári Helgason <kthelgason@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42789}
diff --git a/sdk/objc/api/peerconnection/RTCRtpTransceiver.h b/sdk/objc/api/peerconnection/RTCRtpTransceiver.h
index 1701f68..39a88f5 100644
--- a/sdk/objc/api/peerconnection/RTCRtpTransceiver.h
+++ b/sdk/objc/api/peerconnection/RTCRtpTransceiver.h
@@ -123,7 +123,12 @@
  * by WebRTC for this transceiver.
  * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-setcodecpreferences
  */
-- (void)setCodecPreferences:(NSArray<RTC_OBJC_TYPE(RTCRtpCodecCapability) *> *)codecs;
+- (BOOL)setCodecPreferences:(NSArray<RTC_OBJC_TYPE(RTCRtpCodecCapability) *> *_Nullable)codecs
+                      error:(NSError **_Nullable)error;
+
+/** Deprecated version of [RTCRtpTransceiver setCodecPreferences:error:] */
+- (void)setCodecPreferences:(NSArray<RTC_OBJC_TYPE(RTCRtpCodecCapability) *> *_Nullable)codecs
+    RTC_OBJC_DEPRECATED("Use setCodecPreferences:error: instead.");
 
 /** An update of directionality does not take effect immediately. Instead,
  *  future calls to createOffer and createAnswer mark the corresponding media
diff --git a/sdk/objc/api/peerconnection/RTCRtpTransceiver.mm b/sdk/objc/api/peerconnection/RTCRtpTransceiver.mm
index eb0ad96..a7f2818 100644
--- a/sdk/objc/api/peerconnection/RTCRtpTransceiver.mm
+++ b/sdk/objc/api/peerconnection/RTCRtpTransceiver.mm
@@ -108,12 +108,26 @@
   _nativeRtpTransceiver->StopInternal();
 }
 
-- (void)setCodecPreferences:(NSArray<RTC_OBJC_TYPE(RTCRtpCodecCapability) *> *)codecs {
+- (BOOL)setCodecPreferences:(NSArray<RTC_OBJC_TYPE(RTCRtpCodecCapability) *> *)codecs
+                      error:(NSError **)error {
   std::vector<webrtc::RtpCodecCapability> codecCapabilities;
-  for (RTC_OBJC_TYPE(RTCRtpCodecCapability) * rtpCodecCapability in codecs) {
-    codecCapabilities.push_back(rtpCodecCapability.nativeRtpCodecCapability);
+  if (codecs) {
+    for (RTC_OBJC_TYPE(RTCRtpCodecCapability) * rtpCodecCapability in codecs) {
+      codecCapabilities.push_back(rtpCodecCapability.nativeRtpCodecCapability);
+    }
   }
-  _nativeRtpTransceiver->SetCodecPreferences(codecCapabilities);
+  webrtc::RTCError nativeError = _nativeRtpTransceiver->SetCodecPreferences(codecCapabilities);
+  if (!nativeError.ok() && error) {
+    *error = [NSError
+        errorWithDomain:kRTCRtpTransceiverErrorDomain
+                   code:static_cast<int>(nativeError.type())
+               userInfo:@{@"message" : [NSString stringWithUTF8String:nativeError.message()]}];
+  }
+  return nativeError.ok();
+}
+
+- (void)setCodecPreferences:(NSArray<RTC_OBJC_TYPE(RTCRtpCodecCapability) *> *)codecs {
+  [self setCodecPreferences:codecs error:nil];
 }
 
 - (NSString *)description {
diff --git a/sdk/objc/base/RTCMacros.h b/sdk/objc/base/RTCMacros.h
index 114ced0..7ab9005 100644
--- a/sdk/objc/base/RTCMacros.h
+++ b/sdk/objc/base/RTCMacros.h
@@ -23,6 +23,9 @@
 #define RTC_OBJC_EXPORT
 #endif
 
+// Macro used to mark a function as deprecated.
+#define RTC_OBJC_DEPRECATED(msg) __attribute__((deprecated(msg)))
+
 // Internal macros used to correctly concatenate symbols.
 #define RTC_SYMBOL_CONCAT_HELPER(a, b) a##b
 #define RTC_SYMBOL_CONCAT(a, b) RTC_SYMBOL_CONCAT_HELPER(a, b)
diff --git a/sdk/objc/unittests/RTCPeerConnectionFactory_xctest.m b/sdk/objc/unittests/RTCPeerConnectionFactory_xctest.m
index 7d42b6b..fe9d83d 100644
--- a/sdk/objc/unittests/RTCPeerConnectionFactory_xctest.m
+++ b/sdk/objc/unittests/RTCPeerConnectionFactory_xctest.m
@@ -465,7 +465,10 @@
     }
     XCTAssertNotNil(targetCodec);
 
-    [tranceiver setCodecPreferences:@[ targetCodec ]];
+    NSError *error = nil;
+    BOOL result = [tranceiver setCodecPreferences:@[ targetCodec ] error:&error];
+    XCTAssertTrue(result);
+    XCTAssertNil(error);
 
     @autoreleasepool {
       dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);