Skip to content

Commit 708b5fd

Browse files
committed
Add XML documentation to all public types and members
1 parent c38ce97 commit 708b5fd

13 files changed

Lines changed: 251 additions & 29 deletions

CorePush/Apple/ApnPushType.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,24 @@
11
namespace CorePush.Apple;
22

3+
/// <summary>
4+
/// The type of APNs push notification. Required for iOS 13+.
5+
/// See <see href="https://developer.apple.com/documentation/usernotifications/sending-notification-requests-to-apns">Apple documentation</see>.
6+
/// </summary>
37
public enum ApnPushType
48
{
9+
/// <summary>
10+
/// Background notification that wakes the app to perform a task.
11+
/// Must set apns-priority to 5.
12+
/// </summary>
513
Background,
14+
15+
/// <summary>
16+
/// Visible notification that displays an alert, plays a sound, or badges the app icon.
17+
/// </summary>
618
Alert,
19+
20+
/// <summary>
21+
/// VoIP push notification. Requires the VoIP push entitlement in your app.
22+
/// </summary>
723
Voip
8-
}
24+
}

CorePush/Apple/ApnSender.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ public class ApnSender : IApnSender
3838
private readonly HttpClient http;
3939
private readonly IJsonSerializer serializer;
4040

41-
/// <param name="http">A <see cref="HttpClient"/> dedicated to this <see cref="ApnSender"/>. Do not use a shared <see cref="HttpClient"/> instance, since its instance-level state may be modified. However, its <see cref="HttpClientHandler" can be shared.</param>
41+
/// <summary>
42+
/// Creates a new Apple Push Notification sender with default JSON serialization.
43+
/// </summary>
44+
/// <param name="settings">Apple Push Notification settings (team ID, key, bundle ID, etc.).</param>
45+
/// <param name="http">A <see cref="HttpClient"/> dedicated to this <see cref="ApnSender"/>. Do not use a shared <see cref="HttpClient"/> instance, since its instance-level state may be modified. However, its <see cref="HttpClientHandler"/> can be shared.</param>
4246
public ApnSender(ApnSettings settings, HttpClient http) : this(settings, http, new DefaultCorePushJsonSerializer())
4347
{
4448
}

CorePush/Apple/ApnServerType.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
1-
namespace CorePush.Apple;
1+
namespace CorePush.Apple;
22

3+
/// <summary>
4+
/// Specifies the APNs server environment to send push notifications to.
5+
/// </summary>
36
public enum ApnServerType
47
{
8+
/// <summary>
9+
/// Apple sandbox environment for development and testing.
10+
/// Uses api.development.push.apple.com.
11+
/// </summary>
512
Development,
13+
14+
/// <summary>
15+
/// Apple production environment for live apps.
16+
/// Uses api.push.apple.com.
17+
/// </summary>
618
Production
7-
}
19+
}

CorePush/Apple/ApnSettings.cs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,38 @@
11
namespace CorePush.Apple;
22

3+
/// <summary>
4+
/// Configuration settings for Apple Push Notification service (APNs).
5+
/// Uses token-based authentication with a .p8 key file from the Apple Developer portal.
6+
/// </summary>
37
public class ApnSettings
48
{
59
/// <summary>
6-
/// p8 certificate string
10+
/// The contents of the .p8 private key file downloaded from the Apple Developer portal.
11+
/// Can include or omit the PEM header/footer lines.
712
/// </summary>
813
public string P8PrivateKey { get; set; }
914

1015
/// <summary>
11-
/// 10 digit p8 certificate id. Usually a part of a downloadable certificate filename
16+
/// The 10-character Key ID for the .p8 key, found in the Apple Developer portal
17+
/// or as part of the downloaded .p8 filename.
1218
/// </summary>
13-
public string P8PrivateKeyId { get; set; }
19+
public string P8PrivateKeyId { get; set; }
1420

1521
/// <summary>
16-
/// Apple 10 digit team id
22+
/// Your 10-character Apple Developer Team ID, visible in the Apple Developer portal
23+
/// under Membership details.
1724
/// </summary>
1825
public string TeamId { get; set; }
1926

2027
/// <summary>
21-
/// App slug / bundle name
28+
/// The bundle identifier of your app (e.g. "com.example.myapp"),
29+
/// used as the apns-topic header value.
2230
/// </summary>
2331
public string AppBundleIdentifier { get; set; }
2432

2533
/// <summary>
26-
/// Development or Production server
34+
/// The APNs server environment: <see cref="ApnServerType.Development"/> for sandbox
35+
/// or <see cref="ApnServerType.Production"/> for live apps.
2736
/// </summary>
2837
public ApnServerType ServerType { get; set; }
29-
}
38+
}

CorePush/Apple/ApnsResponse.cs

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,126 @@
1-
namespace CorePush.Apple;
1+
namespace CorePush.Apple;
22

3+
/// <summary>
4+
/// Represents the response from the Apple Push Notification service.
5+
/// </summary>
36
public class ApnsResponse
47
{
8+
/// <summary>
9+
/// Indicates whether the push notification was accepted by APNs.
10+
/// </summary>
511
public bool IsSuccess { get; set; }
612

13+
/// <summary>
14+
/// Error details returned by APNs when the notification was rejected. Null on success.
15+
/// </summary>
716
public ApnsError Error { get; set; }
817
}
918

19+
/// <summary>
20+
/// Error information returned by APNs when a push notification is rejected.
21+
/// </summary>
1022
public class ApnsError
1123
{
1224
/// <summary>
13-
/// Use <see cref="ApnsErrorReasons"/> to compare against
25+
/// The error reason string returned by APNs.
26+
/// Compare against constants in <see cref="ApnsErrorReasons"/>.
1427
/// </summary>
1528
public string Reason {get; set;}
29+
30+
/// <summary>
31+
/// For <see cref="ApnsErrorReasons.Unregistered"/> errors, the last time APNs confirmed
32+
/// the device token was valid, as a UNIX epoch timestamp in milliseconds.
33+
/// </summary>
1634
public long? Timestamp {get; set; }
1735
}
1836

1937
/// <summary>
20-
/// https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html#//apple_ref/doc/uid/TP40008194-CH11-SW15
38+
/// Constants for all APNs error reason strings.
39+
/// See <see href="https://developer.apple.com/documentation/usernotifications/handling-notification-responses-from-apns">Apple documentation</see>.
2140
/// </summary>
2241
public static class ApnsErrorReasons
2342
{
43+
/// <summary>The collapse identifier exceeds the maximum allowed size.</summary>
2444
public const string BadCollapseId = "BadCollapseId";
45+
46+
/// <summary>The specified device token is invalid (e.g. wrong size or contains invalid characters).</summary>
2547
public const string BadDeviceToken = "BadDeviceToken";
48+
49+
/// <summary>The apns-expiration value is invalid.</summary>
2650
public const string BadExpirationDate = "BadExpirationDate";
51+
52+
/// <summary>The apns-id value is invalid.</summary>
2753
public const string BadMessageId = "BadMessageId";
54+
55+
/// <summary>The apns-priority value is invalid.</summary>
2856
public const string BadPriority = "BadPriority";
57+
58+
/// <summary>The apns-topic value is invalid.</summary>
2959
public const string BadTopic = "BadTopic";
60+
61+
/// <summary>The device token doesn't match the specified topic.</summary>
3062
public const string DeviceTokenNotForTopic = "DeviceTokenNotForTopic";
63+
64+
/// <summary>One or more headers are repeated.</summary>
3165
public const string DuplicateHeaders = "DuplicateHeaders";
66+
67+
/// <summary>Idle timeout.</summary>
3268
public const string IdleTimeout = "IdleTimeout";
69+
70+
/// <summary>The device token was not specified in the request path.</summary>
3371
public const string MissingDeviceToken = "MissingDeviceToken";
72+
73+
/// <summary>The apns-topic header is required when the client is connected using a certificate that supports multiple topics.</summary>
3474
public const string MissingTopic = "MissingTopic";
75+
76+
/// <summary>The notification payload is empty.</summary>
3577
public const string PayloadEmpty = "PayloadEmpty";
78+
79+
/// <summary>Pushing to this topic is not allowed.</summary>
3680
public const string TopicDisallowed = "TopicDisallowed";
81+
82+
/// <summary>The certificate is invalid.</summary>
3783
public const string BadCertificate = "BadCertificate";
84+
85+
/// <summary>The client certificate doesn't match the target environment (sandbox vs. production).</summary>
3886
public const string BadCertificateEnvironment = "BadCertificateEnvironment";
87+
88+
/// <summary>The provider token is stale and a new token should be generated.</summary>
3989
public const string ExpiredProviderToken = "ExpiredProviderToken";
90+
91+
/// <summary>The specified action is not allowed.</summary>
4092
public const string Forbidden = "Forbidden";
93+
94+
/// <summary>The provider token is not valid, or the token signature could not be verified.</summary>
4195
public const string InvalidProviderToken = "InvalidProviderToken";
96+
97+
/// <summary>No provider certificate was used to connect to APNs, and the authorization header is missing or no provider token is specified.</summary>
4298
public const string MissingProviderToken = "MissingProviderToken";
99+
100+
/// <summary>The request contained an invalid path.</summary>
43101
public const string BadPath = "BadPath";
102+
103+
/// <summary>The specified HTTP method is not allowed. Use POST.</summary>
44104
public const string MethodNotAllowed = "MethodNotAllowed";
105+
106+
/// <summary>The device token is inactive for the specified topic. The <see cref="ApnsError.Timestamp"/> field contains the last valid timestamp.</summary>
45107
public const string Unregistered = "Unregistered";
108+
109+
/// <summary>The notification payload is too large (max 4096 bytes).</summary>
46110
public const string PayloadTooLarge = "PayloadTooLarge";
111+
112+
/// <summary>The provider has made too many token update requests in too short a time.</summary>
47113
public const string TooManyProviderTokenUpdates = "TooManyProviderTokenUpdates";
114+
115+
/// <summary>Too many requests were sent to APNs. Retry with exponential back-off.</summary>
48116
public const string TooManyRequests = "TooManyRequests";
117+
118+
/// <summary>An internal server error occurred on the APNs side.</summary>
49119
public const string InternalServerError = "InternalServerError";
120+
121+
/// <summary>The APNs service is unavailable. Retry later.</summary>
50122
public const string ServiceUnavailable = "ServiceUnavailable";
51-
public const string Shutdown = "Shutdown";
52-
}
123+
124+
/// <summary>The APNs server is shutting down.</summary>
125+
public const string Shutdown = "Shutdown";
126+
}

CorePush/Firebase/FirebaseError.cs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,44 @@
1-
namespace CorePush.Firebase;
1+
namespace CorePush.Firebase;
22

3+
/// <summary>
4+
/// Error information returned by the Firebase Cloud Messaging HTTP v1 API.
5+
/// </summary>
36
public class FirebaseError
47
{
8+
/// <summary>
9+
/// Additional details about the error, such as the FCM-specific error code.
10+
/// </summary>
511
public class Detail
612
{
13+
/// <summary>
14+
/// The protobuf "@type" URL describing this detail entry.
15+
/// </summary>
716
public string Type { get; set; }
17+
18+
/// <summary>
19+
/// The FCM-specific error code (e.g. "UNREGISTERED", "INVALID_ARGUMENT").
20+
/// See <see href="https://firebase.google.com/docs/cloud-messaging/send-message#rest">FCM error codes</see>.
21+
/// </summary>
822
public string ErrorCode { get; set; }
923
}
1024

25+
/// <summary>
26+
/// The HTTP status code returned by FCM.
27+
/// </summary>
1128
public int Code { get; set; }
29+
30+
/// <summary>
31+
/// A human-readable error message describing what went wrong.
32+
/// </summary>
1233
public string Message { get; set; }
34+
35+
/// <summary>
36+
/// The gRPC status string (e.g. "INVALID_ARGUMENT", "NOT_FOUND", "PERMISSION_DENIED").
37+
/// </summary>
1338
public string Status { get; set; }
39+
40+
/// <summary>
41+
/// An array of additional error detail objects with FCM-specific error codes.
42+
/// </summary>
1443
public Detail[] Details { get; set; }
1544
}
Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
1-
namespace CorePush.Firebase;
1+
namespace CorePush.Firebase;
22

3+
/// <summary>
4+
/// Represents the response from the Firebase Cloud Messaging HTTP v1 API.
5+
/// </summary>
36
public class FirebaseResponse
47
{
8+
/// <summary>
9+
/// The identifier of the sent message in the format "projects/*/messages/{message_id}".
10+
/// Populated on success; null on failure.
11+
/// </summary>
512
public string Name { get; set; }
13+
14+
/// <summary>
15+
/// Error details returned by FCM when the request fails. Null on success.
16+
/// </summary>
617
public FirebaseError Error { get; set; }
7-
}
18+
}

CorePush/Firebase/FirebaseSettings.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,18 @@
22

33
namespace CorePush.Firebase;
44

5+
/// <summary>
6+
/// Configuration settings for Firebase Cloud Messaging (FCM) HTTP v1 API.
7+
/// This record maps directly to the Google Service Account JSON key file
8+
/// (e.g. myproject-12345-abc123123.json) downloaded from the Firebase Console.
9+
/// </summary>
10+
/// <param name="ProjectId">The Firebase/GCP project ID (e.g. "myproject-12345").</param>
11+
/// <param name="PrivateKey">The PEM-encoded RSA private key from the service account key file.</param>
12+
/// <param name="ClientEmail">The service account email address (e.g. "firebase-adminsdk-xxxxx@myproject.iam.gserviceaccount.com").</param>
13+
/// <param name="TokenUri">The OAuth 2.0 token endpoint URL, typically "https://oauth2.googleapis.com/token".</param>
514
public record FirebaseSettings(
615
[property: JsonPropertyName("project_id")] string ProjectId,
716
[property: JsonPropertyName("private_key")] string PrivateKey,
817
[property: JsonPropertyName("client_email")] string ClientEmail,
918
[property: JsonPropertyName("token_uri")] string TokenUri
10-
);
19+
);

CorePush/Interfaces/IApnSender.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,23 @@
66

77
namespace CorePush.Interfaces;
88

9+
/// <summary>
10+
/// Interface for sending Apple Push Notifications via the APNs HTTP/2 API.
11+
/// </summary>
912
public interface IApnSender
1013
{
14+
/// <summary>
15+
/// Sends a push notification to an Apple device.
16+
/// </summary>
17+
/// <param name="notification">The notification payload object. Will be serialized to JSON.
18+
/// See <see href="https://developer.apple.com/documentation/usernotifications/generating-a-remote-notification">Apple payload documentation</see>.</param>
19+
/// <param name="deviceToken">The target device token (hex string) obtained from the device at registration.</param>
20+
/// <param name="apnsId">Optional unique notification identifier. APNs returns this in its response. If omitted, APNs generates a new UUID.</param>
21+
/// <param name="apnsExpiration">The UNIX epoch timestamp (seconds) when the notification expires. 0 means immediate delivery only.</param>
22+
/// <param name="apnsPriority">The notification priority: 10 for immediate delivery, 5 for power-saving delivery.</param>
23+
/// <param name="apnPushType">The push notification type. Required for iOS 13+ and watchOS 6+.</param>
24+
/// <param name="cancellationToken">Cancellation token.</param>
25+
/// <returns>A <see cref="PushResult"/> indicating success or failure with status code and error details.</returns>
1126
Task<PushResult> SendAsync(
1227
object notification,
1328
string deviceToken,
@@ -16,4 +31,4 @@ Task<PushResult> SendAsync(
1631
int apnsPriority = 10,
1732
ApnPushType apnPushType = ApnPushType.Alert,
1833
CancellationToken cancellationToken = default);
19-
}
34+
}
Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
using System.Threading;
22
using System.Threading.Tasks;
33

4-
using CorePush.Firebase;
54
using CorePush.Models;
65

76
namespace CorePush.Interfaces;
87

8+
/// <summary>
9+
/// Interface for sending push notifications via Firebase Cloud Messaging (FCM) HTTP v1 API.
10+
/// </summary>
911
public interface IFirebaseSender
1012
{
13+
/// <summary>
14+
/// Sends a push notification through Firebase Cloud Messaging.
15+
/// </summary>
16+
/// <param name="payload">The FCM message payload object. Will be serialized to JSON.
17+
/// See <see href="https://firebase.google.com/docs/cloud-messaging/send-message">FCM message format</see>.</param>
18+
/// <param name="cancellationToken">Cancellation token.</param>
19+
/// <returns>A <see cref="PushResult"/> indicating success or failure with status code and error details.</returns>
1120
Task<PushResult> SendAsync(object payload, CancellationToken cancellationToken = default);
12-
}
21+
}

0 commit comments

Comments
 (0)