Xojo Conferences

Platforms to show: All Mac Windows Linux Cross-Platform

Required plugins for this example: MBS MacBase Plugin, MBS MacCF Plugin, MBS Main Plugin, MBS Util Plugin
You find this example project in your Plugins Download as a Xojo project file within the examples folder: /MacExtras/Sparkle/PatchApp
This example is the version from Thu, 6th Apr 2016.
Project "PatchApp.rbp"
Class App Inherits Application
Const kEditClear = "&Delete"
Const kFileQuit = "&Quit"
Const kFileQuitShortcut = ""
EventHandler Sub Open() // find app to patch dim f as FolderItem = GetFolderItem("") dim folders() as FolderItem = f.TrueFoldersMBS dim n as integer // find build folder for each folder as FolderItem in folders if Left(folder.Name, 13) = "Builds - Test" then // find platform folders dim subfolders() as FolderItem = folder.TrueFoldersMBS for each subfolder as FolderItem in subfolders // find apps dim appFolders() as FolderItem = subfolder.TrueFoldersMBS for each appFolder as FolderItem in appFolders if Right(appFolder.name,4) = ".app" then patch appFolder n = n + 1 end if next next end if next MsgBox "Patched "+str(n)+" apps" End EventHandler
Function FindFile(name as string) As FolderItem // Look for file in parent folders from executable on dim parent as FolderItem = app.ExecutableFile.Parent while parent<>Nil dim file as FolderItem = parent.Child(name) if file<>Nil and file.Exists then Return file end if parent = parent.Parent wend End Function
Private Function FixInfoPlist(appFolder as folderitem, feedurl as string) As boolean // this method will fail if the application is write protected dim r as BinaryStream dim s as string dim o as CFObjectMBS dim d as CFDictionaryMBS dim e as CFMutableDictionaryMBS dim b as CFBinaryDataMBS dim key,value as CFStringMBS dim name as string dim ContentsFolder as FolderItem = appFolder.TrueChild("Contents") if ContentsFolder = nil then Return false dim InfoPlist as FolderItem = ContentsFolder.TrueChild("Info.plist") if InfoPlist = nil then Return false r= InfoPlist.OpenAsBinaryFile(true) if r=nil then return false s=r.Read(r.Length) if lenb(s)=0 then Return false b=NewCFBinaryDataMBSStr(s) o=NewCFObjectMBSFromXML(b) if o isa CFDictionaryMBS then d=CFDictionaryMBS(o) e=d.Edit key=NewCFStringMBS("SUFeedURL") value=NewCFStringMBS(feedurl) e.Add key,value key=NewCFStringMBS("SUPublicDSAKeyFile") value=NewCFStringMBS("dsa_pub.pem") e.Add key,value // Make XML from CFMutableDictionary b=e.XML // Make RB String s=b.Str // save r.Position=0 r.Write s r.Length=r.Position // cut away rest of file Return true end if End Function
Private Sub Patch(appFolder as FolderItem) dim ContentsFolder as FolderItem = appFolder.Child("Contents") dim ResourcesFolder as FolderItem = ContentsFolder.Child("Resources") dim FrameworksFolder as FolderItem = ContentsFolder.Child("Frameworks") // you may change your info.plist yourself or let the app change itself on the first run. if FixInfoPlist(appFolder, "https://www.monkeybreadsoftware.de/SparkleTest/appcast.xml") then // first run else MsgBox "Failed to change the info.plist file." Return end if // add public key dim PubFile as FolderItem = FindFile("dsa_pub.pem") if PubFile = nil or not PubFile.Exists then MsgBox "You need a dsa_pub.pem file with your public key" else PubFile.CopyFileTo ResourcesFolder end if // add Sparkle Framework dim Is32bitApp as Boolean dim Is64bitApp as Boolean dim bundle as NSBundleMBS = NSBundleMBS.bundleWithPath(appFolder) dim executableArchitectures() as integer = bundle.executableArchitectures for each executableArchitecture as integer in executableArchitectures Select case executableArchitecture case NSBundleMBS.NSBundleExecutableArchitectureI386 Is32bitApp = true case NSBundleMBS.NSBundleExecutableArchitecturePPC break // not supported here case NSBundleMBS.NSBundleExecutableArchitecturePPC64 break // not supported here case NSBundleMBS.NSBundleExecutableArchitectureX86_64 Is64bitApp = true else break // you found a new one? end Select next if Is32bitApp then dim sf as FolderItem = FindFile("Sparkle 32-bit") dim ff as FolderItem = sf.Child("Sparkle.framework") ff.CopyFileTo FrameworksFolder end if if Is64bitApp then dim sf as FolderItem = FindFile("Sparkle 64-bit") dim ff as FolderItem = sf.Child("Sparkle.framework") ff.CopyFileTo FrameworksFolder end if End Sub
End Class
Class Window1 Inherits Window
Control StaticText1 Inherits Label
ControlInstance StaticText1 Inherits Label
End Control
End Class
MenuBar MenuBar1
MenuItem FileMenu = "&File"
MenuItem FileQuit = "#App.kFileQuit"
MenuItem EditMenu = "&Edit"
MenuItem EditUndo = "&Undo"
MenuItem UntitledMenu1 = "-"
MenuItem EditCut = "Cu&t"
MenuItem EditCopy = "&Copy"
MenuItem EditPaste = "&Paste"
MenuItem EditClear = "#App.kEditClear"
MenuItem UntitledMenu0 = "-"
MenuItem EditSelectAll = "Select &All"
End MenuBar
End Project

Feedback, Comments & Corrections

The items on this page are in the following plugins: MBS MacExtras Plugin.

MBS Xojo blog