I am trying to automate some certificate handling for our build system.
I am exporting my certificate using the following commands:
security create-keychain -p foobar tempKeyChain
security unlock-keychain -p foobar tempKeyChain
security add-certificates -k tempKeyChain afile.cer
security export -k tempKeyChain -t certs -f pkcs12 -o afile.p12
security delete-keychain tempKeyChain
The .p12 file generated looks good and I can open it with the "Keychain Access" app and the certificate loaded looks OK.
The problem is that the build scripts perform the following:
security create-keychain -p password mytest
security unlock-keychain -p password mytest
security set-keychain-settings -u -t 12000 mytest
security import afile.p12 -k mytest -T /usr/bin/codesign
1 certificate imported.
security set-key-partition-list -S apple-tool:,apple:,codesign: -k password mytest
security: SecItemCopyMatching: The specified item could not be found in the keychain.
Note the error returned by 'security set-key-partition-list' :
"The specified item could not be found in the keychain."
If I take my afile.p12 load it into my key chain using the "Keychain Access" app and then export it from there as a p12 file and then execute the above code using the p12 file created by the the "Keychain Access" app the 'security set-key-partition-list' command works.
Can anyone explain this?
Post
Replies
Boosts
Views
Activity
I would like to be able to have a script do what Xcode does when it allows me to choose a team and then update the development certificate for that team and download the provisioning files.
I can do this for my own app where I have generated an API key but I would like to do this for other teams where I only have developer access.
I have a files provider app that seems to be working perfectly except for one thing. If I have a directory open in the files provider app and then put the app into the backround and while in the background a file is renamed in the open directory via some other app, then when the files app comes back into the foreground it shows the file with the old name as well as the new name.
I can see via logging that the FileproviderEnumerator is being closed when the app is moved to the background and then reopened when it is moved back into the foreground and I can also see that the correct file names are loaded into it when enumerating.
It looks like the files app doesn't check to see if what it currently has in its cache matches what was just loaded and remove anything that is missing.
To make it more confusing this only appears to be a problem on some devices and not others. It is a problem on my iPad running iPadOS 15.2.1.
I have tried having the parent app, which did the file rename send a change notification but that doesn't seem to work either. If I call the following in my app:
[NSFileProviderManager.defaultManager signalEnumeratorForContainerItemIdentifier:identifier completionHandler:^(NSError * _Nullable error){
if (error != nil)
NSLog(@"signalEnumeratorForContainerItemIdentifier error:%@", error);
else {
NSLog(@"signalEnumeratorForContainerItemIdentifier OK");
}
}];
I see the following message in the console log from the fileproviderd:
[DEBUG] Received error NSError: Cocoa 3072 "" while sending didChangeItemID:completionHandler: on behalf of myApp[955]
Do I need to explicetly tell the files app when a file has been deleted or renamed?
Hi,
Since Xcode 13 it looks like a CFBundleVersion with format 1.2.3 is no longer considered valid. I am happy to change this to a simple integer value so long as it will not cause problems for customers upgrading their existing apps that have the 3 part CFBundleVersion.
My jenkins build process uses 'xcrun altool --upload-app' to upload builds for test flight which all worked well until I switched to Xcode 13. In Xcode 13 the app was uploaded but instead of using the CFBundleVersion from the app as the build number is generated its own. So now the latest build has build numbers 7 rather than the correct build number which should look like 4.5.12345.
I have since updated my scripts to use 'xcrun altool --upload-package' using --bundle-version to set the build number but it will not allow me to upload anything because it sees build number 7 as being higher than 4.5.12346.
I have marked the builds with incorrect build numbers as rejected but that doesn't help.
Is there any way to get around this?
Updating to a new app version is not really a solution.
I have a working fileprovider extension but if I go to the photo album, for example, and share a photo and choose 'Save to Files' my files provider location appears in the list but is grey and inactive so it cannot be chosen.
What do I need to do so that it is enabled?
In my file provider the URL path I get when the a file is modified and the files app calls itemChangedAtURL starts with "/var/..." but in all other cases the URLs start with "/private/var/...".
As a result when I call [self persistentIdentifierForItemAtURL: url] I get nil back because it doesn't recognize the path.
I know that /var is actually a link to /private/var but am I expected to resolve this internally?
Here is some of my code:
- (nullable NSFileProviderItemIdentifier)persistentIdentifierForItemAtURL:(NSURL *)url {
//NSLog(@"FileProviderExtension persistentIdentifierForItemAtURL");
// resolve the given URL to a persistent identifier
if (!url || ![url isFileURL])
return nil;
NSString *prefixPath = [_myRoot stringByAppendingPathComponent:@"/"];
NSString* urlPath = [url path];
NSLog(@"FileProviderExtension persistentIdentifierForItemAtURL prefixPath:%@ urlPath:%@", prefixPath, urlPath);
if (!prefixPath || !urlPath || (urlPath.length <= prefixPath.length)) {
NSLog(@"FileProviderExtension bad-URL persistentIdentifierForItemAtURL prefixPath:%@ urlPath:%@", prefixPath, urlPath);
return nil;
}
NSRange prefixRange = [urlPath rangeOfString:prefixPath];
if ((prefixRange.location == NSNotFound) || (prefixRange.length == 0)){
NSLog(@"FileProviderExtension bad-URL persistentIdentifierForItemAtURL prefixPath:%@ urlPath:%@ prefixRange :%lu", prefixPath, urlPath, prefixRange.length);
return nil;
}
return [urlPath substringWithRange:NSMakeRange(prefixRange.length, urlPath.length - prefixRange.length)];;
}
- (void)itemChangedAtURL:(NSURL *)url {
NSLog(@"FileProviderExtension myPlaceholder itemChangedAtURL: %@", url);
NSFileProviderItemIdentifier itemIdentifier = [self persistentIdentifierForItemAtURL: url];
if (itemIdentifier)
[self notifyPathChanged:[self parentIdentifierForItemIdentifier: itemIdentifier]];
}
I have implemented a file provider extension that seems to be working.
I need to be able to block users from renaming files or folders to illegal names such as a name containing a '/' for example.
In renameItemWithIdentifier
I can scan the name and return an error but all the user sees is an ugly generic error message displaying an error domain and an error code.
Is there any way to display my own error message?
Does the finder support NSFilePromiseProvider?
My guess is no, at least for pasting files.
Maybe someone with inside knowledge of the finder can answer this so other people do not waist time trying to get this to work.
I have an app that has a finder extension. What I would like to do is add a 'copy' menu item for files in my virtual file system that would allow my app to perform the actual file copy to the paste destination. The NSFilePromiseProvider looks like it would allow me to do just that if I could only get it to work.
I have include my test app code which I have not been able to get to work. The NSFilePromiseProvider method
filePromiseProvider:fileNameForType: gets called but the strange thing is that the clipboard viewer show an empty string for the 'com.apple.pasteboard.promised-file-name'.
@interface ClipboardMacPromise : NSFilePromiseProvider<NSFilePromiseProviderDelegate>
@end
@implementation ClipboardMacPromise
- (id)initWithFileType:(NSString*)type
{
NSLog(@"filePromiseProvider Init");
return [super initWithFileType:type delegate:self];
}
- (NSString *)filePromiseProvider:(NSFilePromiseProvider*)filePromiseProvider fileNameForType:(NSString *)fileType
{
NSLog(@"filePromiseProvider fileNameForType");
return @"adoc.pdf";
}
- (void)filePromiseProvider:(NSFilePromiseProvider*)filePromiseProvider writePromiseToURL:(NSURL *)url completionHandler:(void (^)(NSError * _Nullable errorOrNil))completionHandler
{
NSLog(@"filePromiseProvider writePromiseToURL");
// Finder can't paste, so we never get here...
}
@end
@interface AppDelegate ()
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSPasteboard* pboard = [NSPasteboard generalPasteboard];
[pboard clearContents];
NSMutableArray* items = [[NSMutableArray alloc] init];
ClipboardMacPromise* object = [[ClipboardMacPromise alloc] initWithFileType:@"com.adobe.pdf"];
//NSURL *object = [[NSURL alloc] initFileURLWithPath:@"/Users/me/adoc.pdf"];
[items addObject:object];
if (![pboard writeObjects:items])
NSLog(@"writeObjects failed");
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}
@end
I would like to be able to display an error message if one of my context menu actions fails.
I have tried doing something like this but it doesn't seem to work:
(IBAction)contextAction:(NSMenuItem *)sender {
NSAlert *alert = [[NSAlert alloc]init];
[alert setMessageText:@"A dialog"];
[alert setInformativeText:@"A message"];
[alert setAlertStyle:NSWarningAlertStyle];
[alert runModal];
[myFinderSync performMenuItemAction:(uint32_t)sender.tag];
}
Hi,I have an automated build process that produces custom apps for different customers. The only thing that is customized is a resource in the app.I would like to be able to just code sign the entire app once and then for each customer just update and code sign the resource.After doing the initial code signing of the app "codesign -vvv --deep --strict myapp.app" shows that everything is OK.I then replace myapp.app//Contents/Resources/CustomFile with a new one and code sign it:codesign -f -s "Developer ID Application: MY Company" --options runtime --keychain "Buildsystem" "myapp.app/Contents/Resources/CustomFile"But then "codesign -vvv --deep --strict myapp.app" shows there is a problem:myapp.app: a sealed resource is missing or invalidfile modified: myapp.app/Contents/Resources/CustomFileCan anybody explain why this doesn't work?My work around is to always update the resource in an unsigned app and then code sign the entire thing.
I have an app for which I use bitrock to generate an installer and then I put that into a disk image for distribution.I do not upload my app for notarization before building the installer but I do notarize the disk image. This appears to be OK and the gatekeeper recognizes the installer and my app is installed.Running 'spctl -a -vv' on the installed app indicates that everything is OK and if I start the app it starts without a problem, but I would have thought that since the app was not notarized that spctl would have reported a problem and gatekeeper would have complained when it was started.Is my process OK or, dispite what spctl reports, I do in fact need to notarize the app be fore it is packaged by bitrock.Barry
I have an automated build process and when I call:xcrun altool --notarize-app -t osx -f myApp.dmg --primary-bundle-id com.me.myapp -u me@me.com -p @env:NotarizePassword --asc-provider MeGmbHIt takes a while but eventuall completes with:No errors uploading 'myApp.dmg'.RequestUUID = f8b23fc1-ebcf-44a9-984c-abf0ad7123a0My script then calls:xcrun stapler staple myApp.dmgwhich returns:Processing: myApp.dmgCloudKit query for myApp.dmg (2/3707747e82a2daf8902310827531a510a471cde1) failed due to "record not found".Could not find base64 encoded ticket in response for 2/3707747e82a2daf8902310827531a510a471cde1The staple and validate action failed! Error 65.But if I try to run the stapler manually later it works.I saw someone else's build script where they had a 20 second sleep before calling the stapler. Is this required?Do I need to go into a loop and keep trying to call the stapler X number of times with a sleep inbetween?