0
# Protocols and Handlers
1
2
Protocol definitions for creating Mail extensions including message decoders, encoders, security handlers, action handlers, and content blockers. This module defines the interfaces that Mail extensions must implement to provide custom functionality.
3
4
## Capabilities
5
6
### MEExtension Protocol
7
8
Base protocol for Mail extensions. All Mail extensions should conform to this protocol.
9
10
```python { .api }
11
# Protocol: MEExtension
12
def handlerForMessageActions(self):
13
"""
14
Return a handler for message actions.
15
16
Returns:
17
Handler object conforming to MEMessageActionHandler protocol, or None
18
"""
19
20
def handlerForMessageSecurity(self):
21
"""
22
Return a handler for message security operations.
23
24
Returns:
25
Handler object conforming to MEMessageSecurityHandler protocol, or None
26
"""
27
28
def handlerForContentBlocker(self):
29
"""
30
Return a handler for content blocking.
31
32
Returns:
33
Handler object conforming to MEContentBlocker protocol, or None
34
"""
35
36
def handlerForComposeSession_(self, session):
37
"""
38
Return a handler for compose sessions.
39
40
Args:
41
session: MEComposeSession instance
42
43
Returns:
44
Handler object conforming to MEComposeSessionHandler protocol, or None
45
"""
46
```
47
48
### MEMessageDecoder Protocol
49
50
Protocol for decoding messages. Extensions implementing this protocol can provide custom message decoding functionality.
51
52
```python { .api }
53
# Protocol: MEMessageDecoder
54
def decodedMessageForMessageData_(self, messageData):
55
"""
56
Decode message data and return a decoded message.
57
58
Args:
59
messageData: NSData containing the raw message data
60
61
Returns:
62
MEDecodedMessage: Decoded message object, or None if decoding failed
63
"""
64
```
65
66
### MEMessageEncoder Protocol
67
68
Protocol for encoding messages. Extensions implementing this protocol can provide custom message encoding functionality.
69
70
```python { .api }
71
# Protocol: MEMessageEncoder
72
def getEncodingStatusForMessage_composeContext_completionHandler_(
73
self, message, composeContext, completionHandler
74
):
75
"""
76
Get encoding status for a message.
77
78
Args:
79
message: The message to get encoding status for
80
composeContext: MEComposeContext with compose information
81
completionHandler: Completion handler: (MEOutgoingMessageEncodingStatus) -> None
82
"""
83
84
def encodeMessage_composeContext_completionHandler_(
85
self, message, composeContext, completionHandler
86
):
87
"""
88
Encode a message for sending.
89
90
Args:
91
message: The message to encode
92
composeContext: MEComposeContext with compose information
93
completionHandler: Completion handler: (MEMessageEncodingResult) -> None
94
"""
95
```
96
97
### MEMessageSecurityHandler Protocol
98
99
Protocol for handling message security operations. Extensions implementing this protocol can provide custom security functionality.
100
101
```python { .api }
102
# Protocol: MEMessageSecurityHandler
103
def extensionViewControllerForMessageContext_(self, messageContext):
104
"""
105
Return a view controller for the message context.
106
107
Args:
108
messageContext: Context information for the message
109
110
Returns:
111
UIViewController: View controller for displaying security information
112
"""
113
114
def extensionViewControllerForMessageSigners_(self, messageSigners):
115
"""
116
Return a view controller for message signers.
117
118
Args:
119
messageSigners: List of MEMessageSigner objects
120
121
Returns:
122
UIViewController: View controller for displaying signer information
123
"""
124
125
def primaryActionClickedForMessageContext_completionHandler_(
126
self, messageContext, completionHandler
127
):
128
"""
129
Handle primary action click for a message.
130
131
Args:
132
messageContext: Context information for the message
133
completionHandler: Completion handler: (NSError or None) -> None
134
"""
135
```
136
137
### MEMessageActionHandler Protocol
138
139
Protocol for handling message actions. Extensions implementing this protocol can provide custom message action functionality.
140
141
```python { .api }
142
# Protocol: MEMessageActionHandler
143
def decideActionForMessage_completionHandler_(self, message, completionHandler):
144
"""
145
Decide what action to take for a message.
146
147
Args:
148
message: MEMessage object to make a decision about
149
completionHandler: Completion handler: (MEMessageActionDecision) -> None
150
"""
151
```
152
153
### MEContentBlocker Protocol
154
155
Protocol for content blocking functionality. Extensions implementing this protocol can provide content filtering capabilities.
156
157
```python { .api }
158
# Protocol: MEContentBlocker
159
def contentRulesJSON(self):
160
"""
161
Return JSON string containing content blocking rules.
162
163
Returns:
164
str: JSON string with content blocking rules in Safari Content Blocker format
165
"""
166
```
167
168
### MEComposeSessionHandler Protocol
169
170
Protocol for handling compose session events and operations. Extensions implementing this protocol can customize the compose experience.
171
172
```python { .api }
173
# Protocol: MEComposeSessionHandler
174
def mailComposeSessionDidBegin_(self, session):
175
"""
176
Called when a compose session begins.
177
178
Args:
179
session: MEComposeSession that began
180
"""
181
182
def mailComposeSessionDidEnd_(self, session):
183
"""
184
Called when a compose session ends.
185
186
Args:
187
session: MEComposeSession that ended
188
"""
189
190
def viewControllerForSession_(self, session):
191
"""
192
Return a view controller for the compose session.
193
194
Args:
195
session: MEComposeSession instance
196
197
Returns:
198
UIViewController: View controller for the compose session
199
"""
200
201
def session_annotateAddressesWithCompletionHandler_(self, session, completionHandler):
202
"""
203
Annotate addresses in a compose session.
204
205
Args:
206
session: MEComposeSession instance
207
completionHandler: Completion handler: (List[MEAddressAnnotation]) -> None
208
"""
209
210
def session_canSendMessageWithCompletionHandler_(self, session, completionHandler):
211
"""
212
Check if a message can be sent in the session.
213
214
Args:
215
session: MEComposeSession instance
216
completionHandler: Completion handler: (NSError or None) -> None
217
"""
218
219
def additionalHeadersForSession_(self, session):
220
"""
221
Provide additional headers for the session.
222
223
Args:
224
session: MEComposeSession instance
225
226
Returns:
227
dict: Dictionary of additional headers, or None
228
"""
229
230
def requiredHeaders(self):
231
"""
232
Return required headers for compose sessions.
233
234
Returns:
235
List[str]: List of required header names, or None
236
"""
237
```
238
239
## Usage Examples
240
241
### Implementing a Message Decoder
242
243
```python
244
import MailKit
245
from Foundation import NSObject
246
247
class CustomMessageDecoder(NSObject):
248
"""Custom message decoder implementation."""
249
250
def decodedMessageForMessageData_(self, messageData):
251
"""Decode custom message format."""
252
try:
253
# Decode the message data
254
# This is where you would implement your custom decoding logic
255
decoded_data = self.decode_custom_format(messageData)
256
257
# Create security information
258
security_info = MailKit.MEMessageSecurityInformation.alloc().initWithSigners_isEncrypted_signingError_encryptionError_(
259
signers=[],
260
isEncrypted=False,
261
signingError=None,
262
encryptionError=None
263
)
264
265
# Create decoded message
266
decoded_message = MailKit.MEDecodedMessage.alloc().initWithData_securityInformation_context_(
267
data=decoded_data,
268
securityInformation=security_info,
269
context=None
270
)
271
272
return decoded_message
273
except Exception as e:
274
print(f"Failed to decode message: {e}")
275
return None
276
277
def decode_custom_format(self, data):
278
"""Implement your custom decoding logic here."""
279
# Placeholder for custom decoding
280
return data
281
```
282
283
### Implementing a Message Action Handler
284
285
```python
286
import MailKit
287
from Foundation import NSObject
288
289
class CustomActionHandler(NSObject):
290
"""Custom message action handler implementation."""
291
292
def decideActionForMessage_completionHandler_(self, message, completionHandler):
293
"""Decide action based on message analysis."""
294
try:
295
# Analyze message to determine action
296
action_decision = self.analyze_message_for_action(message)
297
298
# Call completion handler with decision
299
completionHandler(action_decision)
300
except Exception as e:
301
print(f"Failed to decide action: {e}")
302
completionHandler(None)
303
304
def analyze_message_for_action(self, message):
305
"""Analyze message and return action decision."""
306
# Placeholder for message analysis logic
307
# Return appropriate MEMessageActionDecision
308
return None
309
```
310
311
### Implementing a Content Blocker
312
313
```python
314
import MailKit
315
from Foundation import NSObject
316
import json
317
318
class CustomContentBlocker(NSObject):
319
"""Custom content blocker implementation."""
320
321
def contentRulesJSON(self):
322
"""Return content blocking rules in JSON format."""
323
try:
324
# Define content blocking rules
325
rules = [
326
{
327
"trigger": {
328
"url-filter": ".*tracking.*",
329
"resource-type": ["image"]
330
},
331
"action": {
332
"type": "block"
333
}
334
},
335
{
336
"trigger": {
337
"url-filter": ".*analytics.*"
338
},
339
"action": {
340
"type": "block"
341
}
342
}
343
]
344
345
return json.dumps(rules)
346
except Exception as e:
347
print(f"Failed to generate content rules: {e}")
348
return "[]"
349
```
350
351
### Implementing a Compose Session Handler
352
353
```python
354
import MailKit
355
from Foundation import NSObject
356
357
class CustomComposeSessionHandler(NSObject):
358
"""Custom compose session handler implementation."""
359
360
def mailComposeSessionDidBegin_(self, session):
361
"""Handle compose session beginning."""
362
print("Compose session began")
363
# Perform any initialization needed for the session
364
365
def mailComposeSessionDidEnd_(self, session):
366
"""Handle compose session ending."""
367
print("Compose session ended")
368
# Perform any cleanup needed
369
370
def viewControllerForSession_(self, session):
371
"""Return custom view controller for session."""
372
# Return a custom view controller if needed
373
return None
374
375
def session_annotateAddressesWithCompletionHandler_(self, session, completionHandler):
376
"""Annotate addresses in the session."""
377
try:
378
# Create address annotations
379
annotations = self.create_address_annotations(session)
380
completionHandler(annotations)
381
except Exception as e:
382
print(f"Failed to annotate addresses: {e}")
383
completionHandler([])
384
385
def session_canSendMessageWithCompletionHandler_(self, session, completionHandler):
386
"""Check if message can be sent."""
387
try:
388
# Validate message for sending
389
can_send = self.validate_message_for_sending(session)
390
if can_send:
391
completionHandler(None) # No error means can send
392
else:
393
# Create error for why message cannot be sent
394
error = self.create_validation_error()
395
completionHandler(error)
396
except Exception as e:
397
print(f"Failed to validate message: {e}")
398
completionHandler(e)
399
400
def additionalHeadersForSession_(self, session):
401
"""Provide additional headers."""
402
return {
403
"X-Custom-Extension": "CustomMailExtension",
404
"X-Version": "1.0"
405
}
406
407
def requiredHeaders(self):
408
"""Return required headers."""
409
return ["Subject", "To"]
410
411
def create_address_annotations(self, session):
412
"""Create address annotations for the session."""
413
# Placeholder for annotation creation logic
414
return []
415
416
def validate_message_for_sending(self, session):
417
"""Validate if message can be sent."""
418
# Placeholder for validation logic
419
return True
420
421
def create_validation_error(self):
422
"""Create validation error."""
423
# Placeholder for error creation
424
return None
425
```
426
427
### Implementing a Complete Extension
428
429
```python
430
import MailKit
431
from Foundation import NSObject
432
433
class CompleteMailExtension(NSObject):
434
"""Complete Mail extension implementing multiple protocols."""
435
436
def __init__(self):
437
super().__init__()
438
self.action_handler = CustomActionHandler.alloc().init()
439
self.security_handler = CustomSecurityHandler.alloc().init()
440
self.content_blocker = CustomContentBlocker.alloc().init()
441
442
# MEExtension protocol methods
443
def handlerForMessageActions(self):
444
"""Return message action handler."""
445
return self.action_handler
446
447
def handlerForMessageSecurity(self):
448
"""Return message security handler."""
449
return self.security_handler
450
451
def handlerForContentBlocker(self):
452
"""Return content blocker handler."""
453
return self.content_blocker
454
455
def handlerForComposeSession_(self, session):
456
"""Return compose session handler."""
457
return CustomComposeSessionHandler.alloc().init()
458
459
# Usage in extension main
460
# extension = CompleteMailExtension.alloc().init()
461
```