SwiftDiff is a (partial) port of the Google Diff, Match and Patch Library (google-diff-match-patch) to Swift. The Google Diff, Match and Patch Library was originally written by Neil Fraser.
So far only the diff algorithm has been ported. It allows comparing two blocks of plain text and efficiently returning a list of their differences. It supports detecting in-line text differences.
SwiftDiff is licensed under the Apache License 2.0 – see the LICENSE file for details.
The original Google Diff, Match and Patch Library is also licensed under the same license and Copyright (c) 2006 Google Inc.
diff(text1:"The quick brown fox jumps over the lazy dog.", text2:"That quick brown fox jumped over a lazy dog.")Returns an array of Diff objects:
[Diff(operation:.equal, text:"Th"),Diff(operation:.delete, text:"e"),Diff(operation:.insert, text:"at"),Diff(operation:.equal, text:" quick brown fox jump"),Diff(operation:.delete, text:"s"),Diff(operation:.insert, text:"ed"),Diff(operation:.equal, text:" over "),Diff(operation:.delete, text:"the"),Diff(operation:.insert, text:"a"),Diff(operation:.equal, text:" lazy dog.")]The diffWithIndices function returns IndexedDiff objects that include the exact positions where each diff operation occurs:
lettext1="Hello World"lettext2="Hello Swift"letdiffs=diffWithIndices(text1: text1, text2: text2)
// Returns array of IndexedDiff objects:
// [
// IndexedDiff(operation: .equal, text: "Hello ", startIndex: <index>, endIndex: <index>),
// IndexedDiff(operation: .delete, text: "World", startIndex: <index>, endIndex: <index>),
// IndexedDiff(operation: .insert, text: "Swift", startIndex: <index>, endIndex: <index>)
// ]
// For each IndexedDiff:
// - Equal and Delete operations: startIndex and endIndex refer to positions in text1
// - Insert operations: startIndex and endIndex (same value) refer to the position in text2// Basic diff result without indices
structDiff{letoperation:Operationlettext:String}
// Diff result with string indices
structIndexedDiff{letoperation:Diff.Operationlettext:StringletstartIndex:String.IndexletendIndex:String.Index}
// Diff operations
enumOperation{case equal
case insert
case delete
}// Basic Diff convenience methods
letequalDiff=Diff.equal("text")letinsertDiff=Diff.insert("new text")letdeleteDiff=Diff.delete("old text")
// IndexedDiff convenience methods
letindexedEqual=IndexedDiff.equal("text", startIndex: start, endIndex: end)letindexedInsert=IndexedDiff.insert("new text", at: insertionPoint)letindexedDelete=IndexedDiff.delete("old text", startIndex: start, endIndex: end)SwiftDiff correctly handles Unicode text including emoji, combining characters, and various scripts:
// Chinese
letdiffs=diffWithIndices(text1:"你好世界", text2:"你好宇宙")
// Japanese
letdiffs=diffWithIndices(text1:"こんにちは世界", text2:"こんばんは世界")
// Arabic (RTL)
letdiffs=diffWithIndices(text1:"مرحبا بالعالم", text2:"مرحبا بالكون")
// Emoji and mixed scripts
letdiffs=diffWithIndices(text1:"Hello 👋 World 🌍", text2:"Hello 👋 Swift 🚀")