1- # Objective-C Code Style Guidelines for AI Agents
1+ # Objective-C and Swift Code Style Guidelines for AI Agents
22
33## Overview
44
5- This document provides code style guidelines that AI agents MUST follow when working with this Objective-C codebase. These guidelines are adapted from industry best practices and tailored to match the existing code patterns in this repository.
5+ This document provides code style guidelines that AI agents MUST follow when working with this codebase. These guidelines are adapted from industry best practices and tailored to match the existing Objective-C and Swift patterns in this repository.
66
77## Key Principles
88
@@ -44,7 +44,7 @@ NSString *username = [account username];
4444```objc
4545// Correct (as used in this repository)
4646- (instancetype)initWithUsername:(NSString *)username
47- homeAccountId:(MSALAccountId *)homeAccountId
47+ homeAccountId:(MSIDAccountId *)homeAccountId
4848 environment:(NSString *)environment
4949{
5050 self = [super init];
@@ -127,12 +127,12 @@ if (error)
127127
128128```objc
129129// Correct
130- - (void)acquireTokenWithParameters:(MSALSilentTokenParameters *)parameters
131- completionBlock:(MSALCompletionBlock )completionBlock;
130+ - (void)acquireTokenWithParameters:(MSIDSilentTokenParameters *)parameters
131+ completionBlock:(MSIDCompletionBlock )completionBlock;
132132
133133// For methods exceeding 80 characters, format like a form
134- - (MSALResult *)resultWithTokenResult:(MSIDTokenResult *)result
135- authScheme:(id<MSALAuthenticationSchemeProtocol >)authScheme
134+ - (MSIDResult *)resultWithTokenResult:(MSIDTokenResult *)result
135+ authScheme:(id<MSIDAuthenticationSchemeProtocol >)authScheme
136136 popManager:(MSIDDevicePopManager *)popManager
137137 error:(NSError **)error;
138138```
@@ -145,9 +145,9 @@ if (error)
145145
146146- ` NSString *username ` - clear and concise
147147- ` NSString *accessToken ` - describes the token type
148- - ` MSALAccount *currentAccount` - not just ` account `
148+ - ` MSIDAccount *currentAccount` - not just ` account `
149149- ` MSIDRequestParameters *requestParams ` - abbreviated but clear
150- - ` MSALPublicClientApplicationConfig *config` - clear context
150+ - ` MSIDApplicationConfig *config` - clear context
151151
152152** NOT RECOMMENDED:** Single letter variable names (except loop counters)
153153
@@ -164,21 +164,21 @@ NSString* clientId
164164NSString * clientId
165165```
166166
167- Exception: Constants (` NSString * const MSALErrorDomain ` )
167+ Exception: Constants (` NSString * const MSIDErrorDomain ` )
168168
169169#### Properties vs Instance Variables
170170
171171** SHOULD** use properties instead of naked instance variables.
172172
173173``` objc
174174// Preferred
175- @interface MSALAccount : NSObject
175+ @interface MSIDAccount : NSObject
176176@property (nonatomic ) NSString * username;
177177@property (nonatomic ) NSString * environment;
178178@end
179179
180180// Avoid
181- @interface MSALAccount : NSObject
181+ @interface MSIDAccount : NSObject
182182{
183183 NSString * username;
184184 NSString * environment;
@@ -198,7 +198,7 @@ Exception: Constants (`NSString * const MSALErrorDomain`)
198198
199199``` objc
200200NSString * __weak weakReference;
201- MSALAccount * __autoreleasing autoreleasedAccount;
201+ MSIDAccount * __autoreleasing autoreleasedAccount;
202202```
203203
204204### 8. Naming Conventions
@@ -209,8 +209,8 @@ MSALAccount * __autoreleasing autoreleasedAccount;
209209
210210``` objc
211211// Correct
212- static const NSTimeInterval MSALDefaultTokenRefreshInterval = 300.0 ;
213- static NSString * const MSALErrorDomain = @" MSALErrorDomain " ;
212+ static const NSTimeInterval MSIDDefaultTokenRefreshInterval = 300.0 ;
213+ static NSString * const MSIDInvalidTokenResultKey = @" MSIDInvalidTokenResultKey " ;
214214
215215// Incorrect
216216static const NSTimeInterval refreshInterval = 300.0 ;
@@ -222,7 +222,7 @@ static const NSTimeInterval refreshInterval = 300.0;
222222
223223``` objc
224224NSString *accessToken;
225- MSALAccount *currentAccount;
225+ MSIDALAccount *currentAccount;
226226MSIDRequestParameters *requestParams;
227227```
228228
@@ -231,7 +231,7 @@ MSIDRequestParameters *requestParams;
231231** MUST** be camelCase with lowercase leading word and underscore prefix:
232232
233233``` objc
234- @implementation MSALPublicClientApplication
234+ @implementation MSIDPublicClientApplication
235235{
236236 BOOL _ validateAuthority;
237237 WKWebView * _ customWebview;
@@ -245,12 +245,12 @@ MSIDRequestParameters *requestParams;
245245
246246```objc
247247// Correct
248- @interface NSArray (MSALAccessors )
248+ @interface NSArray (MSIDAccessors )
249249- (id)msidObjectOrNilAtIndex:(NSUInteger)index;
250250@end
251251
252252// Incorrect - may conflict with other libraries
253- @interface NSArray (MSALAccessors )
253+ @interface NSArray (MSIDAccessors )
254254- (id)objectOrNilAtIndex:(NSUInteger)index;
255255@end
256256```
@@ -283,9 +283,9 @@ NSArray *scopes = [NSArray arrayWithObjects:@"user.read", @"mail.read", @"profil
283283**MUST** declare as `static` constants:
284284
285285```objc
286- static NSString * const MSALErrorDomain = @"MSALErrorDomain ";
287- static const CGFloat MSALDefaultTimeout = 30.0;
288- static const NSTimeInterval MSALTokenExpirationBuffer = 300.0;
286+ static NSString * const MSIDInvalidTokenResultKey = @"MSIDInvalidTokenResultKey ";
287+ static const CGFloat MSIDDefaultTimeout = 30.0;
288+ static const NSTimeInterval MSIDTokenExpirationBuffer = 300.0;
289289```
290290
291291** MAY** use ` #define ` only when explicitly used as a macro.
@@ -295,12 +295,11 @@ static const NSTimeInterval MSALTokenExpirationBuffer = 300.0;
295295** MUST** use ` NS_ENUM() ` for enumerations:
296296
297297``` objc
298- typedef NS_ENUM (NSInteger, MSALPromptType )
298+ typedef NS_ENUM (NSInteger, MSIDThrottlingType )
299299{
300- MSALPromptTypeDefault,
301- MSALPromptTypeLogin,
302- MSALPromptTypeConsent,
303- MSALPromptTypeSelectAccount
300+ MSIDThrottlingTypeNone = 0,
301+ MSIDThrottlingType429 = 1,
302+ MSIDThrottlingTypeInteractiveRequired = 2
304303};
305304```
306305
@@ -309,16 +308,11 @@ typedef NS_ENUM(NSInteger, MSALPromptType)
309308**SHALL** declare private properties in class extensions in implementation file:
310309
311310```objc
312- // In MSALPublicClientApplication.m
313- @interface MSALPublicClientApplication()
314- {
315- BOOL _validateAuthority;
316- WKWebView *_customWebview;
317- }
311+ // In MSIDDRSDiscoveryRequest.m
312+ @interface MSIDDRSDiscoveryRequest()
318313
319- @property (nonatomic) MSALPublicClientApplicationConfig *internalConfig;
320- @property (nonatomic) MSIDExternalAADCacheSeeder *externalCacheSeeder;
321- @property (nonatomic) MSIDCacheConfig *msidCacheConfig;
314+ @property (nonatomic) NSString *domain;
315+ @property (nonatomic) MSIDDRSType adfsType;
322316
323317@end
324318```
@@ -345,20 +339,19 @@ typedef NS_ENUM(NSInteger, MSALPromptType)
345339
346340``` objc
347341// Correct (as used in this repository)
348- #import " MSALPublicClientApplication+Internal.h"
349- #import " MSALPromptType_Internal.h"
350- #import " MSALError.h"
351- #import " MSALTelemetryApiId.h"
352- #import " MSIDMacTokenCache.h"
353- #import " MSIDLegacyTokenCacheAccessor.h"
354- #import " MSIDDefaultTokenCacheAccessor.h"
342+ #import " MSIDSSOExtensionSignoutController.h"
343+ #import " MSIDSSOExtensionSignoutRequest.h"
344+ #import " MSIDInteractiveRequestParameters.h"
345+ #import " ASAuthorizationSingleSignOnProvider+MSIDExtensions.h"
346+ #import " MSIDMainThreadUtil.h"
355347
356348// Do NOT group like this
357349// Frameworks
358- @ import Foundation;
350+ # import < Foundation/Foundation.h >
359351
360- // MSAL Core
361- #import " MSALPublicClientApplication.h"
352+ // Extensions
353+ #import " NSString+MSIDExtensions.h"
354+ #import " NSData+MSIDExtensions.h"
362355```
363356
364357### 21. Protocols (Delegates)
@@ -378,25 +371,11 @@ typedef NS_ENUM(NSInteger, MSALPromptType)
378371** SHOULD** use clear formatting for complex blocks:
379372
380373``` objc
381- __auto_type block = ^(MSALResult *result, NSError *msidError, id <MSIDRequestContext> context)
382- {
383- NSError *msalError = [MSALErrorConverter msalErrorFromMsidError:msidError
384- classifyErrors:YES
385- msalOauth2Provider:self.msalOauth2Provider];
386-
387- if (!completionBlock) return;
388-
389- if (parameters.completionBlockQueue)
374+ MSIDRequestCompletionBlock completionBlockWrapper = ^(MSIDTokenResult *result, NSError *error)
390375 {
391- dispatch_async (parameters.completionBlockQueue, ^{
392- completionBlock(result, msalError);
393- });
394- }
395- else
396- {
397- completionBlock(result, msalError);
398- }
399- };
376+ MSID_LOG_WITH_CTX (MSIDLogLevelInfo, self.requestParameters, @"Silent broker xpc flow finished. Result %@, error: %ld error domain: %@, shouldFallBack: %@", _ PII_NULLIFY(result), (long)error.code, error.domain, @(self.fallbackController != nil));
377+ completionBlock(result, error);
378+ };
400379```
401380
402381### 23. Xcode Project Organization
@@ -408,12 +387,72 @@ __auto_type block = ^(MSALResult *result, NSError *msidError, id<MSIDRequestCont
408387
409388---
410389
390+ ## Swift Code Style Rules
391+
392+ ### 1. Formatting and Indentation
393+
394+ - **MUST** use 4-space indentation (no tabs).
395+ - **MUST** keep opening braces on the same line for types, functions, and control flow.
396+ - **SHOULD** keep one blank line between methods for readability.
397+ - **MUST** preserve the existing whitespace style within a file; do not normalize spacing differences between files.
398+
399+ ```swift
400+ class MSIDFlightManagerTests: XCTestCase {
401+ override func setUp() {
402+ super.setUp()
403+ }
404+ }
405+ ```
406+
407+ ### 2. Naming
408+
409+ - ** MUST** use ` MSID ` prefix for library types in Swift when adding new shared types.
410+ - ** MUST** use PascalCase for type names and enum cases.
411+ - ** MUST** use lowerCamelCase for functions, variables, and properties.
412+
413+ ``` swift
414+ public enum Result <T > {
415+ case Success (T)
416+ case Failure (Error )
417+ }
418+ ```
419+
420+ ### 3. Access Control
421+
422+ - ** SHOULD** specify access control (` private ` , ` internal ` , ` public ` ) explicitly.
423+ - ** SHOULD** keep helpers ` private ` /` internal ` and limit exposure in test helpers.
424+
425+ ### 4. Spacing Conventions
426+
427+ - ** MUST** follow the existing spacing conventions in the file for type annotations and ` switch ` cases.
428+ - In this repository you will encounter both ` Type: Protocol ` and ` Type : Protocol ` styles; match the local file.
429+ - In ` switch ` statements, spacing around ` case ` colons must follow the local file style.
430+
431+ ``` swift
432+ struct SecretInfo : Codable {
433+ let id: String
434+ }
435+
436+ switch result {
437+ case .Failure (let err) : return .Failure (err)
438+ case .Success (let list) :
439+ return .Success (list)
440+ }
441+ ```
442+
443+ ### 5. Comments
444+
445+ - ** SHOULD** use ` // MARK: ` separators in tests to group related cases.
446+ - ** MUST** keep comments accurate; remove stale comments.
447+
448+ ---
449+
411450## AI Agent-Specific Guidelines
412451
413452### When Adding New Features:
414453
4154541 . ** Match Existing Patterns** : Analyze similar existing code before implementing
416- 2 . ** Follow MSAL Conventions** : Use ` MSID ` for classes
455+ 2 . ** Follow Common Core Conventions** : Use ` MSID ` for classes
4174563 . ** Maintain Consistency** : Match indentation, spacing, and naming in surrounding code
4184574 . ** Property-First** : Use ` @property ` declarations rather than instance variables
4194585 . ** Error Handling** : Always check return values, never the error variable
@@ -431,7 +470,7 @@ __auto_type block = ^(MSALResult *result, NSError *msidError, id<MSIDRequestCont
4314704 . ** Deprecation** : Use proper deprecation warnings when replacing APIs
4324715 . ** Backward Compatibility** : Consider impact on existing integrations
433472
434- ### Common MSAL Patterns:
473+ ### Common Patterns:
435474
436475#### Error Handling Pattern
437476
@@ -441,15 +480,16 @@ BOOL result = [self performOperationWithError:&msidError];
441480
442481if (!result)
443482{
444- if (error) * error = [ MSALErrorConverter msalErrorFromMsidError: msidError ] ;
445- return NO;
483+ NSString * message = @"Failed perform operation MSIDOperationA"] ;
484+ if (error) * error = MSIDCreateError(MSIDErrorDomain, MSIDErrorInvalidInternalParameter, message, nil, nil, nil, nil, nil, YES);
485+ return nil;
446486}
447487```
448488
449489#### Completion Block Pattern
450490
451491```objc
452- __auto_type block = ^(MSALResult *result, NSError *error)
492+ __auto_type block = ^(MSIDResult *result, NSError *error)
453493{
454494 // Process result
455495
@@ -493,7 +533,7 @@ MSID_LOG_WITH_CTX_PII(MSIDLogLevelInfo, context,
493533- [ ] Imports not grouped (per repository style)
494534- [ ] Delegate methods include sender as first parameter
495535- [ ] No warnings or errors in build
496- - [ ] Follows existing MSAL/ MSID patterns
536+ - [ ] Follows existing MSID patterns
497537
498538---
499539
@@ -545,4 +585,4 @@ All new files **MUST** include the Microsoft copyright header when added to this
545585
546586## Notes
547587
548- This style guide is adapted specifically for AI agents working on the Microsoft Authentication Library (MSAL) for iOS and macOS. When in doubt, prioritize consistency with existing codebase patterns over strict adherence to external style guides.
588+ This style guide is adapted specifically for AI agents working on the Microsoft Authentication Library Common for iOS and macOS. When in doubt, prioritize consistency with existing codebase patterns over strict adherence to external style guides.
0 commit comments