Programowy dostęp do prefiksu Identyfikatora aplikacji

Jak mogę programowo uzyskać dostęp do łańcucha prefiksu identyfikatora pakietu/identyfikatora zespołu/Identyfikatora aplikacji? (To wszystko to samo, o ile mogę powiedzieć).

Używam owijki pęku kluczy UICKeychainStore do utrwalania danych w kilku aplikacjach. Każda z tych aplikacji ma współdzieloną grupę dostępu do pęku kluczy w plisach uprawnień i ma ten sam profil aprowizacji. Domyślnie usługi pęku kluczy używają pierwszej grupy dostępu w pliście jako grupy dostępu do zapisywania dane do. Wygląda to jak "AS234SDG. com. myCompany. SpecificApp" podczas debugowania UICKeychainStore. Chciałbym ustawić grupę dostępu na "AS234SDG. com. myCompany. SharedStuff", ale nie mogę znaleźć sposobu na zaprogramowanie łańcucha" AS234SDG " grupy dostępu i chciałbym uniknąć kodowania go na twardo, jeśli to możliwe.

Author: Jacob Jennings, 2012-07-30

5 answers

Można programowo pobrać identyfikator Seed pakietu, patrząc na atrybut access group (np. kSecAttrAccessGroup) istniejącego elementu pęku kluczy. W poniższym kodzie poszukuję istniejącego wpisu pęku kluczy i tworzę go, jeśli nie istnieje. Po wpisaniu pęku kluczy wyodrębniam z niego informacje o grupie dostępu i zwracam pierwszy komponent grupy dostępu oddzielony przez "."(kropka) jako ID nasion wiązki.

+ (NSString *)bundleSeedID {
    NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys:
                           (__bridge NSString *)kSecClassGenericPassword, (__bridge NSString *)kSecClass,
                           @"bundleSeedID", kSecAttrAccount,
                           @"", kSecAttrService,
                           (id)kCFBooleanTrue, kSecReturnAttributes,
                           nil];
    CFDictionaryRef result = nil;
    OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&result);
    if (status == errSecItemNotFound)
        status = SecItemAdd((__bridge CFDictionaryRef)query, (CFTypeRef *)&result);
    if (status != errSecSuccess)
        return nil;
    NSString *accessGroup = [(__bridge NSDictionary *)result objectForKey:(__bridge NSString *)kSecAttrAccessGroup];
    NSArray *components = [accessGroup componentsSeparatedByString:@"."];
    NSString *bundleSeedID = [[components objectEnumerator] nextObject];
    CFRelease(result);
    return bundleSeedID;
}
 54
Author: David H,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-04 10:05:44

Info.plist może mieć własne informacje i jeśli napiszesz wartość za pomocą $(AppIdentifierPrefix), zostanie ona zastąpiona prefiksem rzeczywistego identyfikatora aplikacji na etapie budowania.

Więc spróbuj tego:

W Twoich informacjach.plist, dodaj informację o prefiksie identyfikatora aplikacji.

<key>AppIdentifierPrefix</key>
<string>$(AppIdentifierPrefix)</string>

Można następnie pobrać go programowo za pomocą Objective-C:

NSString *appIdentifierPrefix =
    [[NSBundle mainBundle] objectForInfoDictionaryKey:@"AppIdentifierPrefix"];

I z Swift:

let appIdentifierPrefix =
    Bundle.main.infoDictionary!["AppIdentifierPrefix"] as! String

Zauważ, że appIdentifierPrefix Kończy się kropką; np. AS234SDG.

 67
Author: Hiron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-26 14:04:52

W swift3: (na podstawie rozwiązania @ Hiron)

Po prostu jedna linia:

var appIdentifierPrefix = Bundle.main.infoDictionary!["AppIdentifierPrefix"] as! String
Biorąc to pod uwagę w Twoich informacjach.plist, dodaj następującą właściwość key-value:

Klucz: AppIdentifierPrefix

String-value: $(AppIdentifierPrefix)

 6
Author: Ronen Rabinovici,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-14 12:36:00

To dobre pytanie, ale aby osiągnąć to, co zamierzałeś zrobić, mogło być rozwiązanie nie wymaga to pobierania identyfikatora nasion pakietu.

Z tego artykułu , o tym samym opakowaniu pęku kluczy, którego używasz:

Domyślnie wybierze pierwszą grupę dostępową określoną w Twoim Uprawnienia.plist podczas pisania i będzie szukał we wszystkich access-groups, gdy nie podano żadnego.

Kluczem będzie wyszukiwanie we wszystkich grupach, w których dostęp udzielony. Aby rozwiązać problem, możesz dodać grupę dostępu wszystkich aplikacji pakietu do swoich uprawnień.plist zamiast używać grupy" shared stuff", umieść $(CFBundleIdentifier) jako pierwszą grupę pęku kluczy (Twój pęk kluczy zapisze w tej grupie) i masz ustawione

 4
Author: Aurelien Porte,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-03 15:16:57

Oto szybka wersja @ David H odpowiedź:

static func bundleSeedID() -> String? {
        let queryLoad: [String: AnyObject] = [
            kSecClass as String: kSecClassGenericPassword,
            kSecAttrAccount as String: "bundleSeedID" as AnyObject,
            kSecAttrService as String: "" as AnyObject,
            kSecReturnAttributes as String: kCFBooleanTrue
        ]

        var result : AnyObject?
        var status = withUnsafeMutablePointer(to: &result) {
            SecItemCopyMatching(queryLoad as CFDictionary, UnsafeMutablePointer($0))
        }

        if status == errSecItemNotFound {
            status = withUnsafeMutablePointer(to: &result) {
                SecItemAdd(queryLoad as CFDictionary, UnsafeMutablePointer($0))
            }
        }

        if status == noErr {
            if let resultDict = result as? Dictionary<String, Any>, let accessGroup = resultDict[kSecAttrAccessGroup as String] as? String {
                let components = accessGroup.components(separatedBy: ".")
                return components.first
            }else {
                return nil
            }
        } else {
            print("Error getting bundleSeedID to Keychain")
            return nil
        }
    }
 2
Author: balkoth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-13 09:49:26