Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  AppGroup.m   Sprache: Unknown

 

Spracherkennung für: .m vermutete Sprache: Abap {ABAP[55] Python[32] Lisp[29]} [Methode: maximale Elemente, drei Dimensionen]

#import "AppGroup.h"
#import "ThreemaFramework/ThreemaFramework-Swift.h"

#define KEY_APP_GROUP_TYPE_APP @"AppGroupTypeApp"
#define KEY_APP_GROUP_TYPE_NOTIFICATION_EXTENSION @"AppGroupTypeNotificationExtension"
#define KEY_APP_GROUP_TYPE_SHARE_EXTENSION @"AppGroupTypeShareExtension"

#define KEY_DID_MIGRATION_CHECK @"DefaultsKeyDidMigrationCheck"

#define THREEMA_NOTIFICATION_EXTENSION_SUFFIX @"NotificationExtension"
#define THREEMA_SHARE_EXTENSION_SUFFIX @"ShareExtension"

#define THREEMA_APP_GROUP_NOTIFICATION_SUFFIX @".SyncAppGroup"

#ifdef DEBUG
static const DDLogLevel ddLogLevel = DDLogLevelVerbose;
#else
static const DDLogLevel ddLogLevel = DDLogLevelWarning;
#endif

/*
    Tooling to determine if extension or app is running. 
    E.g. when the share extension is triggered from within the app there is no other way to know that.
 */


static NSString *appId;
static NSString *groupId;
static CFStringRef appSyncNotificationKey;

static void observerCallback(void);

@implementation AppGroup

+ (void)setAppId:(NSString *)newAppId {
    NSAssert(appId == nil || [appId isEqualToString:newAppId], @"cannot change appId at runtime!");
    
    appId = newAppId;
    appSyncNotificationKey = CFBridgingRetain([NSString stringWithFormat:@"%@%@", appId, THREEMA_APP_GROUP_NOTIFICATION_SUFFIX]);

    [self registerAppGroupSyncObserver];
}

+ (void)setGroupId:(NSString *)newGroupId {
    NSAssert(groupId == nil || [groupId isEqualToString:newGroupId], @"cannot change groupId at runtime!");
    
    groupId = newGroupId;
}

+ (NSString *)groupId {
    NSAssert(groupId != nil, @"groupId not set");
    
    return groupId;
}

+ (void)setActive:(BOOL)active forType:(AppGroupType)type {
    NSAssert(appId != nil, @"appId not set, you need to set an id for the app or extension");

    if (type == AppGroupTypeNone) {
        return;
    }

    // Log AppGroupType, because of connection problem (Notification Extension steals connection from App and contrary)
    DDLogWarn(@"Set AppGroupType %@ to active: %@", [AppGroup nameForType:type], active == YES ? @"YES" : @"NO");

    NSUserDefaults *defaults = [self userDefaults];
    [defaults setBool:active forKey:[self keyForType:type]];
    [defaults synchronize];
}

+ (AppGroupType)getActiveType {
    NSUserDefaults *defaults = [self userDefaults];

    if ([defaults boolForKey:KEY_APP_GROUP_TYPE_NOTIFICATION_EXTENSION]) {
        return AppGroupTypeNotificationExtension;
    }
    else if ([defaults boolForKey:KEY_APP_GROUP_TYPE_SHARE_EXTENSION]) {
        return AppGroupTypeShareExtension;
    }
    else if ([defaults boolForKey:KEY_APP_GROUP_TYPE_APP]) {
        return AppGroupTypeApp;
    }
    else {
        return AppGroupTypeNone;
    }
}

+ (AppGroupType)getCurrentType {
    NSBundle *mainBundle = [NSBundle mainBundle];
    
    if ([mainBundle.bundleIdentifier hasSuffix:THREEMA_NOTIFICATION_EXTENSION_SUFFIX]) {
        return AppGroupTypeNotificationExtension;
    }
    if ([mainBundle.bundleIdentifier hasSuffix:THREEMA_SHARE_EXTENSION_SUFFIX]) {
        return AppGroupTypeShareExtension;
    } else {
        return AppGroupTypeApp;
    }
}

+ (NSString *)getCurrentTypeString {
    NSBundle *mainBundle = [NSBundle mainBundle];
    
    if ([mainBundle.bundleIdentifier hasSuffix:THREEMA_NOTIFICATION_EXTENSION_SUFFIX]) {
        return @"NotificationExtension";
    }
    if ([mainBundle.bundleIdentifier hasSuffix:THREEMA_SHARE_EXTENSION_SUFFIX]) {
        return @"AppGroupTypeShareExtension";
    } else {
        return @"AppGroupTypeApp";
    }
}

+ (void)setMeActive {
    if ([AppGroup getCurrentType] == AppGroupTypeApp) {
        [AppGroup setActive:YES forType:AppGroupTypeApp];
        [AppGroup setActive:NO forType:AppGroupTypeNotificationExtension];
        [AppGroup setActive:NO forType:AppGroupTypeShareExtension];
    }
    else if ([AppGroup getCurrentType] == AppGroupTypeNotificationExtension) {
        [AppGroup setActive:NO forType:AppGroupTypeApp];
        [AppGroup setActive:YES forType:AppGroupTypeNotificationExtension];
        [AppGroup setActive:NO forType:AppGroupTypeShareExtension];
    }
    else if ([AppGroup getCurrentType] == AppGroupTypeShareExtension) {
        [AppGroup setActive:NO forType:AppGroupTypeApp];
        [AppGroup setActive:NO forType:AppGroupTypeNotificationExtension];
        [AppGroup setActive:YES forType:AppGroupTypeShareExtension];
    }
    else {
        [AppGroup setActive:NO forType:AppGroupTypeApp];
        [AppGroup setActive:NO forType:AppGroupTypeNotificationExtension];
        [AppGroup setActive:NO forType:AppGroupTypeShareExtension];
    }
}

+ (void)setMeInactive {
    [AppGroup setActive:NO forType:[AppGroup getCurrentType]];
}

+ (BOOL)amIActive {
   return [AppGroup getCurrentType] == [AppGroup getActiveType];
}

+ (BOOL)areOthersActive {
    if ([AppGroup getActiveType] == AppGroupTypeNone || [AppGroup getActiveType] == [AppGroup getCurrentType]) {
        return NO;
    }
    return YES;
}

+ (NSUserDefaults *)userDefaults {
    static NSUserDefaults *userDefaults;
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        userDefaults = [[NSUserDefaults alloc] initWithSuiteName: [self groupId]];
        if ([userDefaults boolForKey:KEY_DID_MIGRATION_CHECK] == NO) {
            [self migrateDefaults: userDefaults];
        }
    });
    
    return userDefaults;
}

+ (void)migrateDefaults:(NSUserDefaults *)userDefaults {
    NSUserDefaults *oldDefaults = [NSUserDefaults standardUserDefaults];

    // Only the values the app actually stored: `dictionaryRepresentation` would also migrate the
    // launch arguments set in the scheme (e.g. feature flags)
    NSDictionary *oldValues = [oldDefaults persistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];

    for (NSString *key in oldValues) {
        [userDefaults setObject:oldValues[key] forKey:key];
    }
    
    [userDefaults setBool:YES forKey:KEY_DID_MIGRATION_CHECK];
    [userDefaults synchronize];
}

+ (void)resetUserDefaults {
    NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
    [[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
    [[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[AppGroup groupId]];
}

+ (NSString *)keyForType:(AppGroupType)type {
    switch (type) {
        case AppGroupTypeApp:
            return KEY_APP_GROUP_TYPE_APP;
            
        case AppGroupTypeNotificationExtension:
            return KEY_APP_GROUP_TYPE_NOTIFICATION_EXTENSION;
                        
        case AppGroupTypeShareExtension:
            return KEY_APP_GROUP_TYPE_SHARE_EXTENSION;
                        
        default:
            DDLogError(@"unknown AppGroupType %d", type);
            return KEY_APP_GROUP_TYPE_SHARE_EXTENSION;
    }
}

+ (NSString *)nameForType:(AppGroupType)type {
    switch (type) {
        case AppGroupTypeApp: return @"App";
        case AppGroupTypeShareExtension: return @"ShareExtension";
        case AppGroupTypeNotificationExtension: return @"NotificationExtension";
        case AppGroupTypeNone: return @"None";
        default:
            NSAssert(NO, @"Unknown App Group type");
            return @"Unknown";
    }
}

#pragma mark - inter app communication as seen in (https://developer.apple.com/videos/wwdc/2015/?id=224)

+ (void)registerAppGroupSyncObserver {
    if ([AppGroup getCurrentType] != AppGroupTypeApp) {
        // Otherwise notification gets consumed by extension
        return;
    }
    
    CFNotificationCenterRef nc = CFNotificationCenterGetDarwinNotifyCenter();
    CFNotificationCenterAddObserver(nc,
                                    NULL,
                                    (CFNotificationCallback)observerCallback,
                                    appSyncNotificationKey,
                                    NULL,
                                    CFNotificationSuspensionBehaviorCoalesce);
}

+ (void)notifyAppGroupSyncNeeded {
    if ([AppGroup getCurrentType] == AppGroupTypeApp) {
        // Otherwise notification fires by app itself
        return;
    }

    CFNotificationCenterRef nc = CFNotificationCenterGetDarwinNotifyCenter();
    CFNotificationCenterPostNotification(nc,
                                         appSyncNotificationKey,
                                         nil,
                                         nil,
                                         TRUE);
}

@end

// The definition of this global C function should be outside of AppGroup implementation

static void observerCallback(void) {
    [AppGroup refreshDirtyObjects];
};

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet am  2026-11-04) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104850
#Domains=416977