Чаще всего я вижу использование разработчиком codeable
, здесь я использую пользователя в качестве примера:
YourDataModel.swift
struct User: Codable {
var userId: String = ""
var name: String = ""
var profileImageData: Data? }
UserDefaults .swift
import Foundation
extension UserDefaults {
/// The current user of the application, see `./Models/User.swift`
var currentUser: User? {
get {
guard let userData = self.object(forKey: #function) as? Data else { return nil }
return try? JSONDecoder().decode(User.self, from: userData)
}
set {
guard let newuser = newValue else { return }
if let userData = try? JSONEncoder().encode(newuser) {
self.set(userData, forKey: #function)
}
}
}
}
Преобразовать данные в данные json ... #function
- это имя функции или значения, т. е.
// For the case the user doesn't yet exist.
if ( UserDefaults.standard.currentUser == nil ) {
// Create a new user
user = User()
// Generate an id for the user, using a uuid.
user?.userId = UUID().uuidString
} else {
// otherwise, fetch the user from user defaults.
user = UserDefaults.standard.currentUser
}
Вы хотите использовать это:
Enumeration<URL> resources = Thread.currentThread().getContextClassLoader().getResources("META-INF/MANIFEST.MF");
можно проанализировать URL для выяснения, КОТОРЫЕ сотрясают декларацию если от и затем читают URL через getInputStream () для парсинга декларации.
Вот то, что я нашел что работы:
packageVersion.java:
package com.company.division.project.packageversion;
import java.io.IOException;
import java.io.InputStream;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
public class packageVersion
{
void printVersion()
{
try
{
InputStream stream = getClass().getResourceAsStream("/META-INF/MANIFEST.MF");
if (stream == null)
{
System.out.println("Couldn't find manifest.");
System.exit(0);
}
Manifest manifest = new Manifest(stream);
Attributes attributes = manifest.getMainAttributes();
String impTitle = attributes.getValue("Implementation-Title");
String impVersion = attributes.getValue("Implementation-Version");
String impBuildDate = attributes.getValue("Built-Date");
String impBuiltBy = attributes.getValue("Built-By");
if (impTitle != null)
{
System.out.println("Implementation-Title: " + impTitle);
}
if (impVersion != null)
{
System.out.println("Implementation-Version: " + impVersion);
}
if (impBuildDate != null)
{
System.out.println("Built-Date: " + impBuildDate);
}
if (impBuiltBy != null)
{
System.out.println("Built-By: " + impBuiltBy);
}
System.exit(0);
}
catch (IOException e)
{
System.out.println("Couldn't read manifest.");
}
}
/**
* @param args
*/
public static void main(String[] args)
{
packageVersion version = new packageVersion();
version.printVersion();
}
}
Вот является соответствие build.xml:
<project name="packageVersion" default="run" basedir=".">
<property name="src" location="src"/>
<property name="build" location="bin"/>
<property name="dist" location="dist"/>
<target name="init">
<tstamp>
<format property="TIMESTAMP" pattern="yyyy-MM-dd HH:mm:ss" />
</tstamp>
<mkdir dir="${build}"/>
<mkdir dir="${build}/META-INF"/>
</target>
<target name="compile" depends="init">
<javac debug="on" srcdir="${src}" destdir="${build}"/>
</target>
<target name="dist" depends = "compile">
<mkdir dir="${dist}"/>
<property name="version.num" value="1.0.0"/>
<buildnumber file="build.num"/>
<manifest file="${build}/META-INF/MANIFEST.MF">
<attribute name="Built-By" value="${user.name}" />
<attribute name="Built-Date" value="${TIMESTAMP}" />
<attribute name="Implementation-Vendor" value="Company" />
<attribute name="Implementation-Title" value="PackageVersion" />
<attribute name="Implementation-Version" value="${version.num} (b${build.number})"/>
<section name="com/company/division/project/packageversion">
<attribute name="Sealed" value="false"/>
</section>
</manifest>
<jar destfile="${dist}/packageversion-${version.num}.jar" basedir="${build}" manifest="${build}/META-INF/MANIFEST.MF"/>
</target>
<target name="clean">
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
<target name="run" depends="dist">
<java classname="com.company.division.project.packageversion.packageVersion">
<arg value="-h"/>
<classpath>
<pathelement location="${dist}/packageversion-${version.num}.jar"/>
<pathelement path="${java.class.path}"/>
</classpath>
</java>
</target>
</project>
Можно получить доступ к декларации (или любой другой) файл в банке при использовании того же загрузчика класса для того, как использовался для загрузки классов.
this.getClass().getClassLoader().getResourceAsStream( ... ) ;
, Если Вы - многопоточное использование следующее:
Thread.currentThread().getContextClassLoader().getResourceAsStream( ... ) ;
Это - также действительно полезная техника для включения конфигурационного файла по умолчанию в банке.
ClassLoader.getResource (Строка) загрузит первую декларацию, которую это находит на пути к классу, который может быть декларацией для некоторого другого файла JAR. Таким образом Вы можете или перечислять все декларации для нахождения той, которая Вы хотите или используете некоторый другой механизм, такой как файл свойств с уникальным именем.
Я буду также обычно использовать файл версий. Я создам один файл на банку, так как каждая банка могла иметь свою собственную версию.
Просто не используйте декларацию. Создайте foo.properties.original файл, с содержанием, таким как версия = ВЕРСИЯ
И там та же задача Вы издаете неприятный звук, можно сделать копию к copu foo.properties.original и затем
Я обнаружил, что замечание McDowell верно - какой файл MANIFEST.MF будет взят, зависит от classpath и может быть не тем, который нужен. Я использую этот
String cp = PCAS.class.getResource(PCAS.class.getSimpleName() + ".class").toString();
cp = cp.substring(0, cp.indexOf(PCAS.class.getPackage().getName()))
+ "META-INF/MANIFEST.MF";
Manifest mf = new Manifest((new URL(cp)).openStream());
который я адаптировал из текст ссылки
Вы можете получить манифест для произвольного класса в произвольном jar-файле без анализа URL-адреса класса (который может быть хрупким). Просто найдите ресурс, который, как вы знаете, находится в нужной банке, и затем подключитесь к JarURLConnection.
Если вы хотите, чтобы код работал, когда класс не упакован в jar, добавьте проверку instanceof для типа возвращаемого URL-соединения. Классы в распакованной иерархии классов будут возвращать внутреннее Sun FileURLConnection вместо JarUrlConnection. Затем вы можете загрузить манифест, используя один из методов InputStream, описанных в других ответах.
@Test
public void testManifest() throws IOException {
URL res = org.junit.Assert.class.getResource(org.junit.Assert.class.getSimpleName() + ".class");
JarURLConnection conn = (JarURLConnection) res.openConnection();
Manifest mf = conn.getManifest();
Attributes atts = mf.getMainAttributes();
for (Object v : atts.values()) {
System.out.println(v);
}
}