Detection of the specific models of Apple devices being used to make a request is more difficult than it is for other vendors.Typically, the 51Degrees approach is to use dynamically generated JavaScript to determine the model on the client-side and pass this back to the server. Some users are unable or unwilling to deploy dynamic JavaScript. In this case 51Degrees have an alternative approach in which the required data is gathered using static JavaScript. This is then passed to the server to determine the Apple model.
This example demonstrates this alternative approach.
This example requires a paid-for data file as the device model properties are not available in the free, 'lite' data file. See our pricing page for details on how to obtain one.
using FiftyOne.Pipeline.Core.FlowElements;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
{
class Program
{
public class Example : AppleExampleBase
{
private IPipeline _pipeline;
{
_pipeline = pipeline;
}
public void Run(TextWriter output)
{
var data = new List<Dictionary<string, object>>()
{
new Dictionary<string, object>()
{
{
FiftyOne.Pipeline.Core.Constants.EVIDENCE_HEADER_USERAGENT_KEY,
"Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1" },
}
};
foreach (var values in data)
{
AnalyseEvidence(values, output);
}
}
private void AnalyseEvidence(
Dictionary<string, object> evidence,
TextWriter output)
{
using (var data = _pipeline.CreateFlowData())
{
StringBuilder message = new StringBuilder();
message.AppendLine("Input values:");
foreach (var entry in evidence)
{
message.AppendLine($"\t{entry.Key}: {entry.Value}");
}
output.WriteLine(message.ToString());
data.AddEvidence(evidence);
data.Process();
message = new StringBuilder();
message.AppendLine("Results:");
var device = data.Get<IDeviceData>();
OutputValue("Model Name(s)", device.HardwareName, message);
output.WriteLine(message.ToString());
}
}
private void OutputValue(string name,
IAspectPropertyValue<IReadOnlyList<string>> value,
StringBuilder message)
{
message.AppendLine(value.HasValue ?
$"\t{name}: " + string.Join(", ", value.Value) :
$"\t{name}: " + value.NoValueMessage);
}
public static void Run(string dataFile, string appleDataFile, TextWriter output)
{
using (var serviceProvider = new ServiceCollection()
.AddLogging(l => l.AddConsole())
.AddTransient<AppleProfileEngineBuilder>()
.AddTransient<DeviceDetectionHashEngineBuilder>()
.AddTransient<PipelineBuilder>()
.AddSingleton((x) =>
{
var appleEngine = x.GetRequiredService<AppleProfileEngineBuilder>()
.SetAutoUpdate(false)
.SetDataUpdateOnStartup(false)
.SetDataFileSystemWatcher(false)
.Build(appleDataFile, false);
var ddEngine = x.GetRequiredService<DeviceDetectionHashEngineBuilder>()
.SetPerformanceProfile(PerformanceProfiles.LowMemory)
.SetAutoUpdate(false)
.SetDataUpdateOnStartup(false)
.SetDataFileSystemWatcher(false)
.Build(dataFile, false);
return x.GetRequiredService<PipelineBuilder>()
.AddFlowElement(appleEngine)
.AddFlowElement(ddEngine)
.Build();
})
.AddTransient<Example>()
.BuildServiceProvider())
{
var engine = serviceProvider.GetRequiredService<IPipeline>()
.GetElement<DeviceDetectionHashEngine>();
if (CheckDataFiles(
serviceProvider.GetRequiredService<ILogger<Program>>(),
engine,
dataFile,
appleDataFile))
{
serviceProvider.GetRequiredService<
Example>().Run(output);
}
}
}
}
static void Main(string[] args)
{
var dataFile = args.Length > 0 ? args[0] :
ExampleUtils.FindFile(Constants.ENTERPRISE_HASH_DATA_FILE_NAME);
var appleDataFile = args.Length > 0 ? args[0] :
ExampleUtils.FindFile(Constants.APPLE_DATA_FILE_NAME);
Example.Run(dataFile, appleDataFile, Console.Out);
}
}
}